Skip to content

Commit

Permalink
FIX: (#145) 판매점 도메인 도메인 계층을 재정의한다
Browse files Browse the repository at this point in the history
  • Loading branch information
anxi01 committed Feb 20, 2025
1 parent bcc9a07 commit c998099
Show file tree
Hide file tree
Showing 15 changed files with 494 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/main/java/com/zerozero/store/domain/model/Store.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public class Store extends BaseEntity {

private UUID userId;

public static Store of(UUID userId, StoreSearchResponse store, List<String> images) {
public static Store create(UUID userId, StoreSearchResponse store, List<String> images) {
return Store.builder()
.kakaoId(store.id())
.name(store.placeName())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.zerozero.store.domain.repository;

import com.zerozero.store.domain.model.Store;
import com.zerozero.store.domain.value.GeoLocation;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;
import java.util.Optional;
import java.util.UUID;

public interface StoreRepository extends JpaRepository<Store, UUID> {

Integer countStoresByUserId(UUID userId);

@Query(value = """
SELECT user_rank.r
FROM (
SELECT u.id AS user_id,
RANK() OVER (ORDER BY COUNT(s.id) DESC) AS r
FROM user u
JOIN store s ON u.id = s.user_id
GROUP BY u.id
) AS user_rank
WHERE user_rank.user_id = :userId
""", nativeQuery = true)
Optional<Integer> findStoreUserRank(@Param("userId") UUID userId);

Store findByNameAndGeoLocation(String name, GeoLocation geoLocation);

List<Store> findAllByUserIdAndDeleted(UUID userId, boolean deleted);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.zerozero.store.domain.request;

public record StoreLocationRequest(
double longitude,
double latitude,
String accessToken
) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package com.zerozero.store.domain.response;

import com.zerozero.image.domain.model.Image;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Builder
public record StoreResponse(

@Schema(description = "판매점 ID", example = "8e3006f4-3a16-11ef-9454-0242ac120002")
UUID id,

@Schema(description = "카카오 ID", example = "25770215")
String kakaoId,

@Schema(description = "판매점 이름", example = "제로 피자")
String name,

@Schema(description = "판매 종류", example = "음식점 > 한식 > 육류,고기")
String category,

@Schema(description = "전화번호", example = "02-525-6692")
String phone,

@Schema(description = "판매점 주소", example = "서울특별시 서초구 서초동")
String address,

@Schema(description = "판매점 도로명 주소", example = "서울특별시 서초구 서초대로50길 82 정원빌딩")
String roadAddress,

@Schema(description = "판매점 x좌표(경도)", example = "127.01275515884753")
String longitude,

@Schema(description = "판매점 y좌표(위도)", example = "37.49206032952165")
String latitude,

@Schema(description = "제로음료 판매 여부", example = "true")
boolean status,

@Schema(description = "제로음료 등록 이미지 목록")
List<String> images,

@Schema(description = "판매점 상세페이지 URL", example = "http://place.map.kakao.com/25770215")
String placeUrl
) {
public static StoreResponse from(com.zerozero.store.domain.model.Store store) {
return StoreResponse.builder()
.id(store.getId())
.kakaoId(store.getKakaoId())
.name(store.getName())
.category(store.getCategory())
.phone(store.getPhone())
.address(store.getAddress().getAddress())
.roadAddress(store.getAddress().getRoadAddress())
.longitude(store.getGeoLocation().getLongitude())
.latitude(store.getGeoLocation().getLatitude())
.status(store.isStatus())
.images(store.getImages().stream().map(Image::getUrl).collect(Collectors.toList()))
.placeUrl(store.getPlaceUrl())
.build();
}

public static StoreResponse from(com.zerozero.store.infrastructure.mongodb.Store store) {
return StoreResponse.builder()
.id(store.getStoreId())
.kakaoId(store.getKakaoId())
.name(store.getName())
.category(store.getCategory())
.phone(store.getPhone())
.address(store.getAddress())
.roadAddress(store.getRoadAddress())
.longitude(store.getLongitude())
.latitude(store.getLatitude())
.status(store.isStatus())
.placeUrl(store.getPlaceUrl())
.build();
}

public static StoreResponse of(StoreSearchResponse storeSearchResponse, UUID storeId, boolean status) {
return StoreResponse.builder()
.id(storeId)
.kakaoId(storeSearchResponse.id())
.name(storeSearchResponse.placeName())
.category(storeSearchResponse.categoryName())
.phone(storeSearchResponse.phone())
.address(storeSearchResponse.addressName())
.roadAddress(storeSearchResponse.roadAddressName())
.longitude(storeSearchResponse.longitude())
.latitude(storeSearchResponse.latitude())
.status(status)
.placeUrl(storeSearchResponse.placeUrl())
.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.zerozero.store.domain.response;

import com.zerozero.store.infrastructure.kakao.search.response.KakaoSearchResponse.Document;

public record StoreSearchResponse(
String id,
String placeName,
String categoryName,
String phone,
String addressName,
String roadAddressName,
String longitude,
String latitude,
String placeUrl,
String distance
) {
public static StoreSearchResponse from(Document document) {
return new StoreSearchResponse(
document.getId(),
document.getPlaceName(),
document.getCategoryName(),
document.getPhone(),
document.getAddressName(),
document.getRoadAddressName(),
document.getX(),
document.getY(),
document.getPlaceUrl(),
document.getDistance()
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.zerozero.store.domain.response;

public record StoreUserRankResponse(
int rank,
int storeReportCount
) {
public static StoreUserRankResponse of(int rank, int storeReportCount) {
return new StoreUserRankResponse(rank, storeReportCount);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.zerozero.store.domain.service;

import com.zerozero.store.domain.model.Store;
import com.zerozero.store.domain.repository.StoreRepository;
import com.zerozero.store.exception.StoreErrorType;
import com.zerozero.store.exception.StoreException;
import com.zerozero.store.infrastructure.mongodb.StoreMongoRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.UUID;

@Service
@RequiredArgsConstructor
@Transactional
public class CreateStoreMongoUseCase {

private final StoreRepository storeRepository;

private final StoreMongoRepository storeMongoRepository;

public void execute(UUID storeId) {
Store store = storeRepository.findById(storeId).orElseThrow(() -> new StoreException(StoreErrorType.NOT_EXIST_STORE));
com.zerozero.store.infrastructure.mongodb.Store storeMongo = com.zerozero.store.infrastructure.mongodb.Store.of(store);
storeMongoRepository.save(storeMongo);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.zerozero.store.domain.service;

import com.zerozero.store.domain.model.Store;
import com.zerozero.store.domain.repository.StoreRepository;
import com.zerozero.store.domain.response.StoreSearchResponse;
import com.zerozero.store.exception.StoreErrorType;
import com.zerozero.store.exception.StoreException;
import com.zerozero.store.infrastructure.rabbitmq.CreateStoreMessageProducer;
import com.zerozero.store.infrastructure.rabbitmq.CreateStoreQueueProperty;
import com.zerozero.store.presentation.request.CreateStoreRequest;
import com.zerozero.user.domain.model.User;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.UUID;

@Service
@RequiredArgsConstructor
@Transactional
public class CreateStoreUseCase {

private final StoreRepository storeRepository;

private final StoreSearcher storeSearcher;

private final CreateStoreQueueProperty createStoreQueueProperty;

public UUID execute(CreateStoreRequest createStoreRequest, User user) {
List<StoreSearchResponse> storeSearchResponses = storeSearcher.search(createStoreRequest.placeName());

StoreSearchResponse storeSearchResponse = storeSearchResponses.stream()
.filter(store ->
createStoreRequest.placeName().equals(store.placeName()) &&
createStoreRequest.longitude().equals(store.longitude()) &&
createStoreRequest.latitude().equals(store.latitude()))
.findFirst()
.orElseThrow(() -> new StoreException(StoreErrorType.NOT_EXIST_STORE));

Store store = Store.create(user.getId(), storeSearchResponse, createStoreRequest.images());
storeRepository.save(store);

UUID storeId = store.getId();
CreateStoreMessageProducer createStoreMessageProducer = new CreateStoreMessageProducer(createStoreQueueProperty, storeId);
createStoreMessageProducer.publishMessage();

return storeId;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.zerozero.store.domain.service;

import com.zerozero.store.domain.repository.StoreRepository;
import com.zerozero.store.domain.response.StoreUserRankResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.UUID;

@Service
@RequiredArgsConstructor
public class GetStoreUserRankUseCase {

private final StoreRepository storeRepository;

public StoreUserRankResponse execute(UUID userId) {
int storeUserRank = storeRepository.findStoreUserRank(userId).orElse(0);
int storeCount = storeRepository.countStoresByUserId(userId);
return StoreUserRankResponse.of(storeUserRank, storeCount);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.zerozero.store.domain.service;

import com.zerozero.auth.exception.AuthErrorType;
import com.zerozero.auth.exception.AuthException;
import com.zerozero.core.util.JwtUtil;
import com.zerozero.store.domain.request.StoreLocationRequest;
import com.zerozero.store.domain.response.StoreResponse;
import com.zerozero.store.infrastructure.mongodb.Store;
import com.zerozero.store.infrastructure.mongodb.StoreMongoRepository;
import com.zerozero.user.domain.model.User;
import com.zerozero.user.domain.repository.UserRepository;
import com.zerozero.user.exception.UserErrorType;
import com.zerozero.user.exception.UserException;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
@Log4j2
public class ReadNearbyStoresUseCase {

private final JwtUtil jwtUtil;

private final UserRepository userRepository;

private final StoreMongoRepository storeMongoRepository;

public static final Double DEFAULT_RADIUS = 1000.0;

public List<StoreResponse> execute(StoreLocationRequest storeLocationRequest) {
String accessToken = storeLocationRequest.accessToken();
if (jwtUtil.isTokenExpired(accessToken)) {
log.error("[ReadNearbyStoresUseCase] Expired access token");
throw new AuthException(AuthErrorType.EXPIRED_TOKEN);
}
UUID userId = jwtUtil.extractUserId(accessToken);
User user = userRepository.findById(userId).orElseThrow(() -> new UserException(UserErrorType.NOT_EXIST_USER));
List<Store> mongoStores = storeMongoRepository.findStoresWithinCoordinatesRadius(storeLocationRequest.longitude(), storeLocationRequest.latitude(), DEFAULT_RADIUS);
return mongoStores.stream()
.map(StoreResponse::from)
.collect(Collectors.toList());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.zerozero.store.domain.service;

import com.zerozero.store.domain.model.Store;
import com.zerozero.store.domain.repository.StoreRepository;
import com.zerozero.store.domain.response.StoreResponse;
import com.zerozero.store.exception.StoreErrorType;
import com.zerozero.store.exception.StoreException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.UUID;

@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class ReadStoreInfoUseCase {

private final StoreRepository storeRepository;

public StoreResponse execute(UUID storeId) {
Store store = storeRepository.findById(storeId).orElseThrow(() -> new StoreException(StoreErrorType.NOT_EXIST_STORE));
return StoreResponse.from(store);
}

}
Loading

0 comments on commit c998099

Please sign in to comment.