Skip to content

Commit

Permalink
Merge pull request #23 from Findy-org/refactor/카이젠
Browse files Browse the repository at this point in the history
[FINDY-36] refactor: 카이젠
  • Loading branch information
Hoya324 authored Nov 17, 2024
2 parents 1629604 + 08d97fc commit 802d7de
Show file tree
Hide file tree
Showing 45 changed files with 535 additions and 295 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import org.findy.findy_be.bookmark.application.register.RegisterYoutubeBookmark;
import org.findy.findy_be.bookmark.application.update.UpdateBookmark;
import org.findy.findy_be.bookmark.dto.request.CreateCustomBookmarkRequest;
import org.findy.findy_be.bookmark.dto.request.RegisterYoutubeBookmarkRequest;
import org.findy.findy_be.bookmark.dto.request.UpdateBookmarkRequest;
import org.findy.findy_be.bookmark.dto.request.YoutubeBookmarkRequest;
import org.findy.findy_be.bookmark.dto.response.BookmarkResponse;
import org.findy.findy_be.common.dto.pagination.request.PagedRequest;
import org.findy.findy_be.common.dto.pagination.response.SliceResponse;
Expand Down Expand Up @@ -39,7 +39,8 @@ public class BookmarkController implements BookmarkAPIPresentation {
private final UpdateBookmark updateBookmark;

@PostMapping("/youtube")
public void registerYoutubeBookmark(@LoginUser User user, @Valid @RequestBody YoutubeBookmarkRequest request) {
public void registerYoutubeBookmark(@LoginUser User user,
@Valid @RequestBody RegisterYoutubeBookmarkRequest request) {
registerYoutubeBookmark.invoke(user, request);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package org.findy.findy_be.bookmark.api.swagger;

import org.findy.findy_be.bookmark.dto.request.CreateCustomBookmarkRequest;
import org.findy.findy_be.bookmark.dto.request.RegisterYoutubeBookmarkRequest;
import org.findy.findy_be.bookmark.dto.request.UpdateBookmarkRequest;
import org.findy.findy_be.bookmark.dto.request.YoutubeBookmarkRequest;
import org.findy.findy_be.bookmark.dto.response.BookmarkResponse;
import org.findy.findy_be.common.dto.pagination.request.PagedRequest;
import org.findy.findy_be.common.dto.pagination.response.SliceResponse;
Expand Down Expand Up @@ -31,7 +31,7 @@ public interface BookmarkAPIPresentation {
@CustomApiResponse(error = "EntityNotFoundException", status = 404, message = "해당 id : {id}의 즐겨찾기가 존재하지 않습니다.", description = "존재하지 않는 즐겨찾기에 접근할 경우"),
@CustomApiResponse(error = "InternalServerError", status = 500, message = "내부 서버 오류가 발생했습니다.", description = "서버 내부에서 예기치 않은 오류가 발생한 경우")
})
void registerYoutubeBookmark(@LoginUser User user, @Valid @RequestBody YoutubeBookmarkRequest request);
void registerYoutubeBookmark(@LoginUser User user, @Valid @RequestBody RegisterYoutubeBookmarkRequest request);

@Operation(summary = "커스텀 북마크 등록", description = "유저가 커스텀 북마크를 등록하는 API", responses = {
@ApiResponse(responseCode = "200", description = "커스텀 북마크 등록 성공"),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package org.findy.findy_be.bookmark.application.register;

import org.findy.findy_be.bookmark.dto.request.YoutubeBookmarkRequest;
import org.findy.findy_be.bookmark.dto.request.RegisterYoutubeBookmarkRequest;
import org.findy.findy_be.user.domain.User;

public interface RegisterYoutubeBookmark {

void invoke(final User user, final YoutubeBookmarkRequest request);
void invoke(final User user, final RegisterYoutubeBookmarkRequest request);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
import java.util.List;

import org.findy.findy_be.bookmark.domain.Bookmark;
import org.findy.findy_be.bookmark.dto.request.YoutubeBookmarkRequest;
import org.findy.findy_be.bookmark.dto.request.RegisterYoutubeBookmarkRequest;
import org.findy.findy_be.bookmark.repository.BookmarkRepository;
import org.findy.findy_be.common.exception.custom.ForbiddenAccessException;
import org.findy.findy_be.place.application.register.BatchRegisterPlace;
import org.findy.findy_be.place.dto.request.RegisterPlaceRequest;
import org.findy.findy_be.marker.application.register.BatchRegisterMarker;
import org.findy.findy_be.marker.dto.request.RegisterYouTubeMarkerRequest;
import org.findy.findy_be.user.domain.User;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
Expand All @@ -24,29 +24,29 @@
public class RegisterYoutubeBookmarkService implements RegisterYoutubeBookmark {

private final BookmarkRepository bookmarkRepository;
private final BatchRegisterPlace batchRegisterPlace;
private final BatchRegisterMarker batchRegisterMarker;

@Override
public void invoke(final User user, final YoutubeBookmarkRequest request) {
List<RegisterPlaceRequest> placeRequests = request.places();
bookmarkRepository.findByUserAndYoutuberId(user, request.youtuberId()).ifPresentOrElse(
existingBookmark -> {
existingBookmark.updateName(request.youtuberName());
validateBookmarkOwner(user, existingBookmark.getUser());
batchRegisterPlace.invoke(existingBookmark, placeRequests);
},
() -> {
log.info("새로운 북마크에 저장합니다.");
Bookmark bookmark = request.toEntity(user);
bookmarkRepository.save(bookmark);
batchRegisterPlace.invoke(bookmark, placeRequests);
}
);
public void invoke(final User user, final RegisterYoutubeBookmarkRequest request) {
List<RegisterYouTubeMarkerRequest> placeRequests = request.places();

bookmarkRepository.findByUserAndYoutuberId(user, request.youtuberId())
.ifPresentOrElse(
existingBookmark -> {
existingBookmark.updateName(request.youtuberName());
validateBookmarkOwner(user, existingBookmark.getUser());
batchRegisterMarker.invoke(existingBookmark, placeRequests);
},
() -> {
log.info("새로운 북마크에 저장합니다.");
Bookmark newBookmark = bookmarkRepository.save(request.toEntity(user));
batchRegisterMarker.invoke(newBookmark, placeRequests);
}
);
}

private void validateBookmarkOwner(User currentUser, User bookmarkUser) {
String bookmarkUserId = bookmarkUser.getUserId();
if (!bookmarkUserId.equals(currentUser.getUserId())) {
if (!bookmarkUser.getUserId().equals(currentUser.getUserId())) {
throw new ForbiddenAccessException(FORBIDDEN_BOOKMARK_ACCESS.getMessage());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public class Bookmark extends BaseTimeEntity {
@JoinColumn(name = "user_id")
private User user;

@OneToMany(mappedBy = "bookmark", cascade = CascadeType.REMOVE, orphanRemoval = true)
@OneToMany(mappedBy = "bookmark", cascade = CascadeType.ALL, orphanRemoval = true)
@Builder.Default
private List<Marker> markers = new ArrayList<>();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

import org.findy.findy_be.bookmark.domain.Bookmark;
import org.findy.findy_be.common.validation.ValidYoutuberId;
import org.findy.findy_be.place.dto.request.RegisterPlaceRequest;
import org.findy.findy_be.marker.dto.request.RegisterYouTubeMarkerRequest;
import org.findy.findy_be.user.domain.User;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;

@Schema(description = "유튜브 즐겨찾기 DTO")
public record YoutubeBookmarkRequest(
public record RegisterYoutubeBookmarkRequest(

@ValidYoutuberId(message = "유튜버 ID는 @으로 시작해야합니다.")
@Schema(description = "유튜버 ID", example = "@iammingki")
Expand All @@ -27,7 +27,7 @@ public record YoutubeBookmarkRequest(
@Schema(description = "유튜브 링크", example = "https://www.youtube.com/watch?v=hE2wMo5Coco")
String youtubeLink,

List<RegisterPlaceRequest> places
List<RegisterYouTubeMarkerRequest> places
) {
public Bookmark toEntity(User user) {
return Bookmark.createYoutubeType(youtuberName, youtuberId, youtuberProfile, youtubeLink, user);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ public enum ErrorCode {
NOT_FOUND_BOOKMARK_BY_ID(NOT_FOUND, "해당 id : %s의 즐겨찾기가 존재하지 않습니다."),
NOT_FOUND_USER(NOT_FOUND, "해당 이메일을 가진 유저가 존재하지 않습니다."),
NOT_FOUND_USER_BY_ID(NOT_FOUND, "해당 id : %s를 가진 유저가 존재하지 않습니다."),
BAD_REQUEST_CATEGORY_NOT_FOUND_ERROR(NOT_FOUND, "해당 input : %s을 가진 카테고리가 없습니다.");
BAD_REQUEST_CATEGORY_NOT_FOUND_ERROR(NOT_FOUND, "해당 input : %s을 가진 카테고리가 없습니다."),
NOT_FOUND_PLACE(NOT_FOUND, "장소를 찾을 수 없습니다. 장소멸: %s, 도로명 주소: %s");

// 500 error

Expand Down
42 changes: 42 additions & 0 deletions src/main/java/org/findy/findy_be/marker/api/MarkerController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package org.findy.findy_be.marker.api;

import org.findy.findy_be.common.dto.pagination.request.PagedRequest;
import org.findy.findy_be.common.dto.pagination.response.SliceResponse;
import org.findy.findy_be.common.meta.LoginUser;
import org.findy.findy_be.marker.api.swagger.MarkerAPIPresentation;
import org.findy.findy_be.marker.application.find.FindAllPagedMarkers;
import org.findy.findy_be.marker.application.register.RegisterMarker;
import org.findy.findy_be.marker.dto.request.RegisterSearchedMarkerRequest;
import org.findy.findy_be.place.dto.response.PlaceResponse;
import org.findy.findy_be.user.domain.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;

@RestController
@RequestMapping("/api/markers")
@RequiredArgsConstructor
public class MarkerController implements MarkerAPIPresentation {

private final RegisterMarker registerMarker;
private final FindAllPagedMarkers findAllPagedMarkers;

@PostMapping("/{bookmarkId}")
public void registerMarker(@LoginUser User user, @PathVariable("bookmarkId") Long bookmarkId,
@Valid @RequestBody RegisterSearchedMarkerRequest request) {
registerMarker.invoke(bookmarkId, request, user.getUserId());
}

@GetMapping("/{bookmarkId}")
public SliceResponse<PlaceResponse> getMarkers(@LoginUser User user, @PathVariable("bookmarkId") Long bookmarkId,
@ModelAttribute PagedRequest request) {
return findAllPagedMarkers.invoke(user.getUserId(), bookmarkId, request.cursor(), request.size());
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package org.findy.findy_be.place.api.swagger;
package org.findy.findy_be.marker.api.swagger;

import org.findy.findy_be.common.dto.pagination.request.PagedRequest;
import org.findy.findy_be.common.dto.pagination.response.SliceResponse;
import org.findy.findy_be.common.meta.CustomApiResponse;
import org.findy.findy_be.common.meta.CustomApiResponses;
import org.findy.findy_be.common.meta.LoginUser;
import org.findy.findy_be.place.dto.request.RegisterSearchedPlaceRequest;
import org.findy.findy_be.marker.dto.request.RegisterSearchedMarkerRequest;
import org.findy.findy_be.place.dto.response.PlaceResponse;
import org.findy.findy_be.user.domain.User;
import org.springframework.web.bind.annotation.ModelAttribute;
Expand All @@ -17,28 +17,29 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;

@Tag(name = "Place API", description = "장소 관련 API")
public interface PlaceAPIPresentation {
@Tag(name = "Marker API", description = "마커 관련 API")
public interface MarkerAPIPresentation {

@Operation(summary = "장소 등록", description = "새로운 장소를 등록하는 API", responses = {
@ApiResponse(responseCode = "200", description = "장소 등록 성공"),
@Operation(summary = "마커 등록", description = "새로운 마커"
+ "를 등록하는 API", responses = {
@ApiResponse(responseCode = "200", description = "마커 등록 성공"),
@ApiResponse(responseCode = "400", description = "유효하지 않은 입력 값")
})
@CustomApiResponses({
@CustomApiResponse(error = "HttpMessageNotReadableException", status = 400, message = "유튜브 즐겨찾기는 장소를 추가할 수 없습니다.", description = "validation에 맞지 않은 요청을 할 경우"),
@CustomApiResponse(error = "EntityNotFoundException", status = 404, message = "해당 id : 1의 즐겨찾기가 존재하지 않습니다.", description = "장소를 저장할 즐겨찾기를 못 찾는 경우"),
@CustomApiResponse(error = "InternalServerError", status = 500, message = "내부 서버 오류가 발생했습니다.", description = "내부 서버 오류")
})
void registerPlace(@LoginUser User user, @PathVariable Long bookmarkId,
@Valid @RequestBody RegisterSearchedPlaceRequest request);
void registerMarker(@LoginUser User user, @PathVariable Long bookmarkId,
@Valid @RequestBody RegisterSearchedMarkerRequest request);

@Operation(summary = "장소 목록 조회", description = "유저의 북마크 장소 목록을 조회하는 API", responses = {
@ApiResponse(responseCode = "200", description = "장소 목록 조회 성공")
@Operation(summary = "마커 목록 조회", description = "유저의 마커 목록을 조회하는 API", responses = {
@ApiResponse(responseCode = "200", description = "마커 조회 성공")
})
@CustomApiResponses({
@CustomApiResponse(error = "IllegalArgumentException", status = 400, message = "잘못된 요청입니다.", description = "잘못된 쿼리 파라미터가 포함된 경우"),
@CustomApiResponse(error = "InternalServerError", status = 500, message = "내부 서버 오류가 발생했습니다.", description = "서버 내부에서 예기치 않은 오류가 발생한 경우")
})
SliceResponse<PlaceResponse> getPlaces(@LoginUser User user, @PathVariable("bookId") Long bookId,
SliceResponse<PlaceResponse> getMarkers(@LoginUser User user, @PathVariable("bookmarkId") Long bookmarkId,
@ModelAttribute PagedRequest request);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
import java.util.List;

import org.findy.findy_be.bookmark.domain.Bookmark;
import org.findy.findy_be.marker.dto.request.RegisterYouTubeMarkerRequest;
import org.findy.findy_be.place.domain.Place;

public interface BatchCreateMarker {
void invoke(final Bookmark bookmark, final List<Place> places);
void invoke(final Bookmark bookmark, final List<Place> places, final List<RegisterYouTubeMarkerRequest> requests);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import java.util.stream.Collectors;

import org.findy.findy_be.bookmark.domain.Bookmark;
import org.findy.findy_be.bookmark.repository.BookmarkRepository;
import org.findy.findy_be.marker.domain.Marker;
import org.findy.findy_be.marker.dto.request.RegisterYouTubeMarkerRequest;
import org.findy.findy_be.marker.repository.MarkerRepository;
import org.findy.findy_be.place.domain.Place;
import org.springframework.stereotype.Service;
Expand All @@ -25,43 +25,55 @@
public class BatchCreateMarkerService implements BatchCreateMarker {

private final MarkerRepository markerRepository;
private final BookmarkRepository bookmarkRepository;

@Override
public void invoke(final Bookmark bookmark, final List<Place> places) {
List<Marker> existingMarkers = markerRepository.findAllByBookmarkAndPlaces(bookmark, places);
public void invoke(final Bookmark bookmark, final List<Place> places,
final List<RegisterYouTubeMarkerRequest> requests) {
Set<Long> existingPlaceIds = findExistingPlaceIds(bookmark, places);

Set<Long> existingPlaceIds = getExistingPlaceIds(existingMarkers);
List<Marker> newMarkers = getNewMarkers(bookmark, places, existingPlaceIds);
List<Marker> newMarkers = createNewMarkers(bookmark, places, requests, existingPlaceIds);

markerRepository.saveAll(newMarkers);
updateMarkersCount(bookmark.getId(), newMarkers);
}

private static List<Marker> getNewMarkers(final Bookmark bookmark, final List<Place> places,
final Set<Long> existingPlaceIds) {
return places.stream()
.filter(place -> !existingPlaceIds.contains(place.getId()))
.map(place -> {
Marker marker = Marker.create(bookmark, place);
marker.changeBookmark(bookmark);
return marker;
})
.collect(Collectors.toList());
saveMarkersAndIncrementCount(bookmark, newMarkers);
}

private static Set<Long> getExistingPlaceIds(final List<Marker> existingMarkers) {
Set<Long> existingPlaceIds;
existingPlaceIds = existingMarkers.stream()
private Set<Long> findExistingPlaceIds(Bookmark bookmark, List<Place> places) {
return markerRepository.findAllByBookmarkAndPlaces(bookmark, places).stream()
.map(marker -> marker.getPlace().getId())
.collect(Collectors.toSet());
return existingPlaceIds;
}

private void updateMarkersCount(final Long bookmarkId, final List<Marker> newMarkers) {
Bookmark bookmark = bookmarkRepository.findById(bookmarkId)
.orElseThrow(() -> new EntityNotFoundException(
String.format(NOT_FOUND_BOOKMARK_BY_ID.getMessage(), bookmarkId)));
private List<Marker> createNewMarkers(Bookmark bookmark, List<Place> places,
List<RegisterYouTubeMarkerRequest> requests, Set<Long> existingPlaceIds) {
return requests.stream()
.filter(request -> !existingPlaceIds.contains(
findPlaceIdByTitleAndRoadAddress(places, request.title(), request.roadAddress())))
.map(request -> createMarker(bookmark, places, request))
.toList();
}

private Marker createMarker(Bookmark bookmark, List<Place> places, RegisterYouTubeMarkerRequest request) {
Place place = findPlaceByTitleAndRoadAddress(places, request.title(), request.roadAddress());
return Marker.createForYoutubeBookmark(request.timestamp(), bookmark, place);
}

private void saveMarkersAndIncrementCount(Bookmark bookmark, List<Marker> newMarkers) {
markerRepository.saveAll(newMarkers);
bookmark.incrementMarkersCount(newMarkers.size());
}

private Place findPlaceByTitleAndRoadAddress(List<Place> places, String title, String roadAddress) {
return places.stream()
.filter(place -> place.getTitle().equals(title) && place.getRoadAddress().equals(roadAddress))
.findFirst()
.orElseThrow(
() -> new EntityNotFoundException(String.format(NOT_FOUND_PLACE.getMessage(), title, roadAddress)));
}

private Long findPlaceIdByTitleAndRoadAddress(List<Place> places, String title, String roadAddress) {
return places.stream()
.filter(place -> place.getTitle().equals(title) && place.getRoadAddress().equals(roadAddress))
.map(Place::getId)
.findFirst()
.orElse(null);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class CreateMarkerService implements CreateMarker {
public void invoke(final Bookmark bookmark, final Place place) {
Optional<Marker> existingMarker = markerRepository.findByBookmarkAndPlace(bookmark, place);
if (existingMarker.isEmpty()) {
Marker marker = Marker.create(bookmark, place);
Marker marker = Marker.createForCustomBookmark(bookmark, place);
markerRepository.save(marker);
marker.changeBookmark(bookmark);
bookmark.incrementMarkersCount(1);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package org.findy.findy_be.place.application.find;
package org.findy.findy_be.marker.application.find;

import org.findy.findy_be.common.dto.pagination.response.SliceResponse;
import org.findy.findy_be.place.dto.response.PlaceResponse;

public interface FindAllPagedPlaces {
SliceResponse<PlaceResponse> invoke(final String userId, final Long bookId, final Long cursor, final int size);
public interface FindAllPagedMarkers {
SliceResponse<PlaceResponse> invoke(final String userId, final Long bookmarkId, final Long cursor, final int size);
}
Loading

0 comments on commit 802d7de

Please sign in to comment.