Skip to content

Commit

Permalink
[feat] 족보에 가게 추가 삭제 API 구현 (#65)
Browse files Browse the repository at this point in the history
* [feat] setting command dto

* [feat] setting repository

* [feat] add logic in Entity

* [feat] add login in service and controller

* [feat] add error code

* [feat] imple repository logic

* [feat] add check data logic

* [refac] change Favorite imageUrl to imageType

* [refac] change FavoriteImage variable name

* [refac] fix wrong code
  • Loading branch information
PicturePark1101 authored Jul 15, 2024
1 parent e7ea8bf commit b8a706f
Show file tree
Hide file tree
Showing 20 changed files with 236 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,22 @@
import org.hankki.hankkiserver.api.favorite.service.command.FavoriteGetCommand;
import org.hankki.hankkiserver.api.favorite.service.command.FavoritePostCommand;
import org.hankki.hankkiserver.api.favorite.controller.request.FavoritePostRequest;
import org.hankki.hankkiserver.api.favorite.service.command.FavoriteStoreDeleteCommand;
import org.hankki.hankkiserver.api.favorite.service.command.FavoriteStorePostCommand;
import org.hankki.hankkiserver.api.favorite.service.command.FavoritesDeleteCommand;
import org.hankki.hankkiserver.auth.UserId;
import org.hankki.hankkiserver.common.code.CommonSuccessCode;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.Mapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.hankki.hankkiserver.api.favorite.service.FavoriteQueryService;
import org.hankki.hankkiserver.api.favorite.service.response.FavoriteFindResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
Expand All @@ -44,6 +50,27 @@ public HankkiResponse<Void> deleteFavorite(@UserId final Long userId, @RequestBo

@GetMapping("/favorites/{favoriteId}")
public HankkiResponse<FavoriteFindResponse> getFavorite(@UserId final Long userId, @PathVariable(name = "favoriteId") final Long favoriteId) {
return HankkiResponse.success(CommonSuccessCode.OK, favoriteQueryService.findFavorite(FavoriteGetCommand.of(userId, favoriteId)));
return HankkiResponse.success(CommonSuccessCode.OK,
favoriteQueryService.findFavorite(FavoriteGetCommand.of(userId, favoriteId)));
}

@PostMapping("/favorites/{favoriteId}/stores/{storeId}")
public HankkiResponse<Void> createFavoriteStore(
@UserId final Long userId,
@PathVariable("favoriteId") final Long favoriteId,
@PathVariable("storeId") final Long storeId
) {
favoriteCommandService.createFavoriteStore(FavoriteStorePostCommand.of(userId, favoriteId, storeId));
return HankkiResponse.success(CommonSuccessCode.CREATED);
}

@DeleteMapping("/favorites/{favoriteId}/stores/{storeId}")
public HankkiResponse<Void> deleteFavoriteStore(
@UserId final Long userId,
@PathVariable("favoriteId") final Long favoriteId,
@PathVariable("storeId") final Long storeId
) {
favoriteCommandService.deleteFavoriteStore(FavoriteStoreDeleteCommand.of(userId, favoriteId, storeId));
return HankkiResponse.success(CommonSuccessCode.NO_CONTENT);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,21 @@
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.hankki.hankkiserver.api.auth.service.UserFinder;
import org.hankki.hankkiserver.api.favorite.service.command.FavoriteStoreDeleteCommand;
import org.hankki.hankkiserver.api.favorite.service.command.FavoriteStorePostCommand;
import org.hankki.hankkiserver.api.favorite.service.command.FavoritesDeleteCommand;
import org.hankki.hankkiserver.api.favoritestore.service.FavoriteStoreDeleter;
import org.hankki.hankkiserver.api.favoritestore.service.FavoriteStoreFinder;
import org.hankki.hankkiserver.api.favoritestore.service.FavoriteStoreUpdater;
import org.hankki.hankkiserver.api.store.service.StoreFinder;
import org.hankki.hankkiserver.common.code.FavoriteStoreErrorCode;
import org.hankki.hankkiserver.common.code.UserErrorCode;
import org.hankki.hankkiserver.common.exception.ConflictException;
import org.hankki.hankkiserver.common.exception.UnauthorizedException;
import org.hankki.hankkiserver.domain.favorite.model.Favorite;
import org.hankki.hankkiserver.api.favorite.service.command.FavoritePostCommand;
import org.hankki.hankkiserver.domain.favoritestore.model.FavoriteStore;
import org.hankki.hankkiserver.domain.store.model.Store;
import org.hankki.hankkiserver.domain.user.model.User;
import org.springframework.stereotype.Service;

Expand All @@ -19,8 +28,11 @@ public class FavoriteCommandService {

private final UserFinder userFinder;
private final FavoriteFinder favoriteFinder;
private final StoreFinder storeFinder;
private final FavoriteUpdater favoriteUpdater;
private final FavoriteStoreUpdater favoriteStoreUpdater;
private final FavoriteStoreDeleter favoriteStoreDeleter;
private final FavoriteStoreFinder favoriteStoreFinder;
private final FavoriteDeleter favoriteDeleter;

@Transactional
Expand All @@ -39,12 +51,45 @@ public void deleteFavorites(final FavoritesDeleteCommand command) {
List<Favorite> favorites = favoriteFinder.findAllByIds(command.favoriteIds());

favorites.forEach(favorite -> {
if (!favorite.getUser().getId().equals(command.userId())) {
throw new UnauthorizedException(UserErrorCode.USER_FORBIDDEN);
}
validateUserAuthorization(favorite.getUser(), userFinder.getUser(command.userId()));
});

favoriteStoreDeleter.deleteAllByFavorites(favorites);
favoriteDeleter.deleteAll(favorites);
}

@Transactional
public Long createFavoriteStore(final FavoriteStorePostCommand command) {

Favorite favorite = favoriteFinder.findByIdWithUser(command.favoriteId());
Store store = storeFinder.findByIdWhereDeletedIsFalse(command.storeId());

if (isAlreadyExistsFavoriteStore(favorite.getId(), store.getId())){
throw new ConflictException(FavoriteStoreErrorCode.FAVORITE_STORE_ALREADY_EXISTED);
};

FavoriteStore favoriteStore = favoriteStoreUpdater.save(FavoriteStore.create(store, favorite));
favorite.updateImageByFavoriteStoreCount(favoriteStoreFinder.countByFavorite(favorite));

return favoriteStore.getId();
}

@Transactional
public void deleteFavoriteStore(final FavoriteStoreDeleteCommand command) {

Favorite favorite = favoriteFinder.findByIdWithUser(command.favoriteId());
favoriteStoreDeleter.delete(favoriteStoreFinder.findByFavoriteIdAndStoreId(favorite.getId(), command.storeId()));

favorite.updateImageByFavoriteStoreCount(favoriteStoreFinder.countByFavorite(favorite));
}

private void validateUserAuthorization(final User findUser, final User commandUser) {
if (!findUser.equals(commandUser)) {
throw new UnauthorizedException(UserErrorCode.USER_FORBIDDEN);
}
}

private boolean isAlreadyExistsFavoriteStore(final Long favoriteId, final Long storeId){
return favoriteStoreFinder.isExist(favoriteId, storeId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.hankki.hankkiserver.common.exception.InternalServerException;
import org.hankki.hankkiserver.domain.favorite.model.Favorite;
import org.hankki.hankkiserver.domain.favorite.repository.FavoriteRepository;
import org.hankki.hankkiserver.domain.favoritestore.model.FavoriteStore;
import org.springframework.stereotype.Component;

@Component
Expand All @@ -14,12 +15,7 @@ public class FavoriteDeleter {

private final FavoriteRepository favoriteRepository;

protected void deleteAll(List<Favorite> favorites) {

try {
favoriteRepository.deleteAll(favorites);
} catch (Exception e) {
throw new InternalServerException(BusinessErrorCode.INTERNAL_SERVER_ERROR);
}
protected void deleteAll(final List<Favorite> favorites) {
favoriteRepository.deleteAll(favorites);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,8 @@ public List<Favorite> findAllByIds(final List<Long> ids) {
public List<Favorite> findAllByUserId(final Long userId) {
return favoriteRepository.findByUserIdOrderByCreatedAtDesc(userId);
}

protected Favorite findByIdWithUser(final Long id) {
return favoriteRepository.findByIdWithUser(id).orElseThrow(() -> new NotFoundException(FavoriteErrorCode.FAVORITE_NOT_FOUND));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ public record FavoritePostCommand(
) {

public static FavoritePostCommand of(final Long userId, final FavoritePostRequest favoritePostRequest) {

return new FavoritePostCommand(userId, favoritePostRequest.title(), favoritePostRequest.details());

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.hankki.hankkiserver.api.favorite.service.command;

public record FavoriteStoreDeleteCommand(
Long userId,
Long favoriteId,
Long storeId
) {

public static FavoriteStoreDeleteCommand of(Long userId, Long favoriteId, Long storeId) {
return new FavoriteStoreDeleteCommand(userId, favoriteId, storeId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.hankki.hankkiserver.api.favorite.service.command;

import org.hankki.hankkiserver.auth.UserId;
import org.springframework.web.bind.annotation.PathVariable;

public record FavoriteStorePostCommand(
Long userId,
Long favoriteId,
Long storeId
) {

public static FavoriteStorePostCommand of(Long userId, Long favoriteId, Long storeId) {
return new FavoriteStorePostCommand(userId, favoriteId, storeId);
}
}
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
package org.hankki.hankkiserver.api.favorite.service.response;

import org.hankki.hankkiserver.domain.store.model.Store;
import org.hankki.hankkiserver.domain.store.model.StoreCategory;

public record FavoriteStoreFindResponse(
Long id,
String name,
String imageUrl,
String imageType,
String category,
int lowestPrice,
int heartCount
) {

public static FavoriteStoreFindResponse of(Store store) {

return new FavoriteStoreFindResponse(
store.getId(),
store.getName(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.hankki.hankkiserver.common.code.BusinessErrorCode;
import org.hankki.hankkiserver.common.exception.InternalServerException;
import org.hankki.hankkiserver.domain.favorite.model.Favorite;
import org.hankki.hankkiserver.domain.favoritestore.model.FavoriteStore;
import org.hankki.hankkiserver.domain.favoritestore.repository.FavoriteStoreRepository;
import org.springframework.stereotype.Component;

Expand All @@ -14,12 +15,11 @@ public class FavoriteStoreDeleter {

private final FavoriteStoreRepository favoriteStoreRepository;

public void deleteAllByFavorites(List<Favorite> favorites) {
public void deleteAllByFavorites(final List<Favorite> favorites) {
favoriteStoreRepository.deleteAllByFavorites(favorites);
}

try {
favoriteStoreRepository.deleteAllByFavorites(favorites);
} catch (Exception e) {
throw new InternalServerException(BusinessErrorCode.INTERNAL_SERVER_ERROR);
}
public void delete(final FavoriteStore favoriteStore) {
favoriteStoreRepository.delete(favoriteStore);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.hankki.hankkiserver.api.favoritestore.service;

import java.util.Optional;
import lombok.RequiredArgsConstructor;
import org.hankki.hankkiserver.common.code.FavoriteStoreErrorCode;
import org.hankki.hankkiserver.common.code.StoreErrorCode;
import org.hankki.hankkiserver.common.exception.NotFoundException;
import org.hankki.hankkiserver.domain.favorite.model.Favorite;
import org.hankki.hankkiserver.domain.favoritestore.model.FavoriteStore;
import org.hankki.hankkiserver.domain.favoritestore.repository.FavoriteStoreRepository;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class FavoriteStoreFinder {

private final FavoriteStoreRepository favoriteStoreRepository;

public int countByFavorite(final Favorite favorite) {
return favoriteStoreRepository.countByFavorite(favorite);
}

public FavoriteStore findByFavoriteIdAndStoreId(final Long favoriteId, final Long storeId) {
return favoriteStoreRepository.findByFavoriteIdAndStoreId(favoriteId, storeId)
.orElseThrow(() -> new NotFoundException(FavoriteStoreErrorCode.FAVORITE_STORE_NOT_FOUND));
}

public boolean isExist(final Long favoriteId, final Long storeId) {
return favoriteStoreRepository.isExist(favoriteId, storeId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package org.hankki.hankkiserver.api.favoritestore.service;

import lombok.RequiredArgsConstructor;
import org.hankki.hankkiserver.domain.favoritestore.model.FavoriteStore;
import org.hankki.hankkiserver.domain.favoritestore.repository.FavoriteStoreRepository;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class FavoriteStoreUpdater {

private final FavoriteStoreRepository favoriteStoreRepository;

public FavoriteStore save(FavoriteStore favoriteStore) {
return favoriteStoreRepository.save(favoriteStore);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ public Store getStoreReference(final Long id) {
return storeRepository.getReferenceById(id);
}

protected Store findByIdWhereDeletedIsFalse(final Long id) {

public Store findByIdWhereDeletedIsFalse(final Long id) {
return storeRepository.findByIdAndIsDeletedIsFalse(id)
.orElseThrow(() -> new NotFoundException(StoreErrorCode.STORE_NOT_FOUND));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package org.hankki.hankkiserver.api.user.service.response;

import org.hankki.hankkiserver.domain.favorite.model.Favorite;
import org.hankki.hankkiserver.domain.favorite.model.FavoriteImage;

public record UserFavoriteResponse(
Long id,
String title,
String imageUrl
FavoriteImage imageUrl
) {

public static UserFavoriteResponse of(Favorite favorite) {
return new UserFavoriteResponse(favorite.getId(), favorite.getName(), favorite.getImageUrl());
return new UserFavoriteResponse(favorite.getId(), favorite.getName(), favorite.getImageType());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
@RequiredArgsConstructor
public enum FavoriteStoreErrorCode implements ErrorCode {

FAVORITE_STORE_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 데이터입니다.");
FAVORITE_STORE_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 데이터입니다."),
FAVORITE_STORE_ALREADY_EXISTED(HttpStatus.CONFLICT, "이미 족보에 추가된 가게입니다.");

private final HttpStatus httpStatus;
private final String message;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ public NotFoundException(ErrorCode errorCode) {
super(errorCode.getMessage());
this.errorCode = errorCode;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,18 @@ public class Favorite extends BaseTimeEntity {

private String detail;

@Enumerated(EnumType.STRING)
@Column(nullable = false)
private String imageUrl;
private FavoriteImage imageType;

@OneToMany(mappedBy = "favorite")
@BatchSize(size = 100)
private List<FavoriteStore> favoriteStores = new ArrayList<>();

public void updateImageByFavoriteStoreCount(int count) {
this.imageType = FavoriteImage.getType(count);
}

public static Favorite create(User user, String name, String detail) {
return Favorite.builder()
.user(user)
Expand All @@ -51,6 +56,6 @@ private Favorite(User user, String name, String detail) {
this.user = user;
this.name = name;
this.detail = detail;
this.imageUrl = "default.com";
this.imageType = FavoriteImage.BASE_IMAGE;
}
}
Loading

0 comments on commit b8a706f

Please sign in to comment.