-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* [feat] 기능 요구사항에 맞게 Store 도메인 엔티티의 인스턴스 필드 반영 기능 요구사항: 가게 이름, 전화번호, 위치 정보, 카테고리, 이용 시간, 최소 주문 금액을 입력해 가게를 등록 notice: - 카테고리 → StoreCategory 도메인 엔티티 - 주소 → Address 임베디드 타입 - 이용 시간 → StoreTime 임베디드 타입 - 도메인 생성 검증은 StoreValidator 에서 절차지향으로 진행 * [feat] 가게 이름 검증 기능 가게 이름은 2글자 ~ 10글자만 가능 * [feat] 가게 주소 검증 기능 - 가게 주소는 송파구만 가능 - 추후 가게 위치 비즈니스 요구사항을 구체화하면, 주소 검증 로직 수정 필요 * [feat] 가게 최소 주문 금액 검증 기능 - 5,000원 이상 - 1,000원 단위 * [feat] 가게 이용 시간 검증 기능 - 가게 시작/종료 시간은 분 단위까지 가능 - 가게 시작 시간은 종료 시간보다 이전 * [feat] 가게 주소 임베디드 타입 정의 임베디드 타입 사용 이유 - 주소는 도시/구/상세주소 같은 정보들로 그룹핑 됨 - 현재는 프로토타입으로서 구 정보만 사용하지만, 가게 주소 비즈니스 요구사항이 구체화되면 다른 정보들도 활용할 여지가 있음 - 구체화가 완료되면, 엔티티로 분리할 것인지 논의 필요 * [feat] 가게 이용 시간 임베디드 타입 정의 임베디드 타입 사용 이유 - 이용 시간은 시작 시간/ 종료 시간 정보로 그룹핑 됨 - LocalDateTime 과 변수명만으로는 비즈니스 요구사항을 명시적으로 표현하기 제약이 있음 * [feat] 가게 카테고리 도메인 엔티티 정의 도메인 엔티티로 분리한 이유: - 가게 카테고리는 DB 레벨에서 관리해야, 추후 카테고리를 추가/생성/삭제할 때 변경 이상에 대처가 용이할 것으로 판단 * [feat] 시간 정보를 제공하는 DateTimeProvider 인터페이스 정의 인터페이스 설계 이유: 날짜 API 를 직접 참조함으로서 테스트하기 어려워지는 코드를 예방하기 위함 * [feat] 고정 시간을 반환하는 DateTimeProvider 테스트용 구현체 시간 관련 로직을 테스트할 때 사용 사용 방법은 javadocs 로 샘플 코드 기재 * [feat] 현재 시간을 반환하는 DateTimeProvider 프로덕션용 구현체 * [feat] DateTimeProvider 구현체인 CurrentDateTime 를 Bean 객체로 설정 * [test] Store 도메인 객체 생성 테스트 - 가게 최소 주문 가격 * [test] Store 도메인 객체 생성 테스트 - 가게 이용 시간 * [test] Store 도메인 객체 생성 테스트 - 가게 이름 * [feat] Store (가게) 도메인 관련 커스텀 예외 정의 Store 와 관련된 예외임을 명시적으로 나타내고자 함 IllegalArgumentException 등 Java 에서 제공하는 기본 예외는 예외의 명시성이 떨어진다 판단 * [feat] 가게 카테고리 생성자 추가 기본 생성자는 애노테이션 사용 및 protected 접근 제어자로 설정 * [feat] StoreRepository JPA 인터페이스 정의 * [test] StoreRepository 가게 저장 기능 테스트 - repository 단위 테스트는 @DataJpaTest 로 최소한의 Bean 만 주입하여 사용 - @SpringBootTest 는 모든 Bean 을 로드하기 때문에 테스트가 무거워짐 * [feat] StoreCategoryRepository JPA 인터페이스 정의 - 가게 카테고리 이름으로 조회하는 시그니쳐 추가 * [test] 가게 카테고리 이름으로 조회하는 기능 테스트 * [feat] VendorRepository JPA 인터페이스 정의 - StoreRepository 단위 테스트를 위해 정의함 - Store 엔티티를 저장할 때, 참조중인 Vendor(Not Null) 를 저장해야 Not-Null Property Exception 이 발생하지 않음 * [feat] 가게 생성을 담당하는 서비스 클래스 구현 - 발생가능한 RunTimeException 은 javadocs 로 명시 * [feat] 가게 등록 요청 DTO - Not Null, 빈값, 빈값 포함한 공백 에 대한 입력 검증은 Bean Validation 으로 검증함 * [test] 가게 등록 서비스 메서드 단위 테스트 * [fix] Order 엔티티의 테이블 이름을 Orders 로 명시 order 는 DBMS 예약어라서 Auto DDL 과정에서 예외가 발생함 * [feat] 인메모리 H2 DB 및 jpa yaml 설정 - datasource: 인메모리 H2 DB를 사용하도록 설정 - h2: h2 웹 콘솔 사용 가능하도록 설정 - jpa: ddl 자동 생성, sql 로깅 설정 - 설정 내용의 depth 가독성이 용이하여, properties 를 yaml 로 변경함 * [refactor] 불필요한 static 키워드 제거 * [refactor] 가게 등록 요청 DTO 패키지 이동 * [feat] 가게와 관련된 예외를 명시하는 ErrorCode Enum 정의 - 가게 관련한 예외의 범주를 ErrorCode Enum 으로 한정하도록 함 - 예외 메시지를 응집하여, 테스트 코드에서 예외 메시지 검증으로 구체적인 검증이 용이하도록 하기 위함 * [refactor] StoreException 을 생성할 때, 가게 관련 ErrorCode Enum 을 생성자 매개변수로 사용하도록 변경 * [test] 가게 등록 서비스 예외 검증을 예외 메시지로 구체적인 검증 * [test] 가게 생성 예외 검증을 예외 메시지로 구체적인 검증 * [fix] Long, LocalDateTime 데이터 타입에 대한 Bean Validation 수정 @notblank 는 String 타입에 적용 가능 * [feat] Store 가게 API 컨트롤러 구현 * [feat] Store 예외 핸들러 구현 * [test] Store 가게 API 컨트롤러 단위 테스트 * [feat] 메뉴카테고리 엔티티 설계 설계 배경: 음식 상품을 등록할 때, 해당 가게에 등록한 음식 카테고리를 조회할 수 있어야함. 이와 연계하여, 매장에 대한 음식 카테고리를 등록할 수 있어야함. Enum 설계도 고려해봤지만, 동적으로 음식 카테고리를 추가하는데 제약이 있고, 메뉴 카테고리 조회에도 제약이 있다고 판단. 연관관계 설명: 메뉴-메뉴카테고리 (다대일): 하나의 메뉴는 하나의 메뉴 카테고리를 갖고, 하나의 메뉴 카테고리는 여러 메뉴에 속한다. 메뉴카테고리-매장 (다대일): 하나의 메뉴카테고리는 하나의 매장에 속하고, 하나의 매장은 여러 메뉴카테고리를 갖는다. * [feat] 음식 상품이 이미지를 반드시 갖도록 Nullable 제약조건 false 로 변경 * [feat] 메뉴 도메인 Null 값 검증 기능 * [feat] 메뉴 도메인 빈 문자열, 공백 문자열 검증 기능 * [feat] 메뉴 이름 길이 검증 기능 * [feat] 메뉴 가격 검증 기능 * [feat] 메뉴 도메인 생성자 및 검증 기능 추가 * [test] Menu 도메인 객체 생성 테스트 - 가게 Null 값 * [test] Menu 도메인 객체 생성 테스트 - 메뉴카테고리 Null 값 * [test] Menu 도메인 객체 생성 테스트 - 메뉴 이름 * [test] Menu 도메인 객체 생성 테스트 - 메뉴 가격 * [test] Menu 도메인 객체 생성 테스트 - 메뉴 사진 url * [feat] 메뉴카테고리 도메인 Null 값 검증 기능 * [feat] 메뉴카테고리 도메인 빈 문자열, 공백 문자열 검증 기능 * [feat] 메뉴카테고리 이름 길이 검증 기능 * [feat] 메뉴카테고리 생성자에 검증 기능 추가 * [feat] 메뉴카테고리 객체 생성 실패 커스텀 예외 * [feat] 메뉴 객체 생성 실패 커스텀 예외 * [test] MenuCategory 도메인 객체 생성 테스트 - 가게 Null 값 * [test] MenuCategory 도메인 객체 생성 테스트 - 이름 * [feat] 점주 ID 기반으로 매장을 조회하는 시그니쳐 추가 점주가 가게 메뉴 등록 할 때, 점주에 대한 가게를 조회하는 로직이 필요함 * [test] 점주 ID 기반으로 매장을 조회하는 기능 테스트 * [feat] MenuCategoryRepository JPA 인터페이스 정의 가게ID와 메뉴카테고리 이름으로 메뉴카테고리를 조회하는 기능 * [test] 가게ID와 메뉴카테고리 이름으로 메뉴카테고리를 조회하는 기능 테스트 * [feat] MenuRepository JPA 인터페이스 정의 * [feat] 메뉴 카테고리를 찾을 수 없는 커스텀 예외 * [feat] 가게를 찾을 수 없는 커스텀 예외 * [feat] @Getter 롬복 추가 * [feat] 가게 메뉴 등록 요청 DTO * [feat] 가게 메뉴 등록 서비스 * [test] 가게 메뉴 등록 서비스 테스트 * [feat] Vendor @Getter 롬복 추가 및 라인 정리 * [test] merge 과정에서 깨지는 테스트코드 수정 및 테스트 * [feat] 가게 메뉴 등록 요청 Bean Validation 예외 메시지 구체화 * [feat] Store 객체 생성 검증 조건 추가 - Null 체크 * [test] 기존 테스트 코드의 Store 객체 생성자에 null 제거 및 테스트 * [feat] 가게 메뉴 등록 요청 DTO에 가게 ID 추가 * [fix] 가게 ID로 가게를 조회하도록 수정 - 점주 - 가게 일대다 관계로, 점주 ID로 조회하면 가게 목록을 조회하게 됨 * [feat] 가게의 점주와 동일한지 검증하는 기능 * [feat] 가게의 점주와 동일하지 않을 때 발생하는 커스텀 예외
- Loading branch information
Showing
22 changed files
with
1,000 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,49 @@ | ||
package camp.woowak.lab.menu.domain; | ||
|
||
import camp.woowak.lab.store.domain.Store; | ||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.FetchType; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.JoinColumn; | ||
import jakarta.persistence.ManyToOne; | ||
import lombok.AccessLevel; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Entity | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class Menu { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "store_id", nullable = false) | ||
private Store store; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "menu_category_id", nullable = false) | ||
private MenuCategory menuCategory; | ||
|
||
@Column(nullable = false) | ||
private String name; | ||
|
||
@Column(nullable = false) | ||
private Integer price; | ||
|
||
@Column(nullable = false) | ||
private String imageUrl; | ||
|
||
public Menu(Store store, MenuCategory menuCategory, String name, Integer price, String imageUrl) { | ||
MenuValidator.validate(store, menuCategory, name, price, imageUrl); | ||
this.store = store; | ||
this.menuCategory = menuCategory; | ||
this.name = name; | ||
this.price = price; | ||
this.imageUrl = imageUrl; | ||
} | ||
|
||
} |
36 changes: 36 additions & 0 deletions
36
src/main/java/camp/woowak/lab/menu/domain/MenuCategory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package camp.woowak.lab.menu.domain; | ||
|
||
import camp.woowak.lab.store.domain.Store; | ||
import jakarta.persistence.Column; | ||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.FetchType; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.JoinColumn; | ||
import jakarta.persistence.ManyToOne; | ||
import lombok.AccessLevel; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Entity | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
public class MenuCategory { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "store_id", nullable = false) | ||
private Store store; | ||
|
||
@Column(nullable = false) | ||
private String name; | ||
|
||
public MenuCategory(Store store, String name) { | ||
MenuCategoryValidator.validate(store, name); | ||
this.store = store; | ||
this.name = name; | ||
} | ||
|
||
} |
38 changes: 38 additions & 0 deletions
38
src/main/java/camp/woowak/lab/menu/domain/MenuCategoryValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
package camp.woowak.lab.menu.domain; | ||
|
||
import camp.woowak.lab.menu.exception.InvalidMenuCategoryCreationException; | ||
import camp.woowak.lab.store.domain.Store; | ||
|
||
public class MenuCategoryValidator { | ||
|
||
private static final int MAX_NAME_LENGTH = 10; | ||
|
||
public static void validate(final Store store, final String name) { | ||
validateNotNull(store, name); | ||
validateNotBlank(name); | ||
validateNameLength(name); | ||
} | ||
|
||
private static void validateNotNull(final Object... targets) { | ||
for (Object target : targets) { | ||
if (target == null) { | ||
throw new InvalidMenuCategoryCreationException(target + "은 Null 이 될 수 없습니다."); | ||
} | ||
} | ||
} | ||
|
||
private static void validateNotBlank(final String... targets) { | ||
for (String target : targets) { | ||
if (target.isBlank()) { | ||
throw new InvalidMenuCategoryCreationException(target + "은 빈 문자열이거나 공백 문자열이 포함될 수 없습니다."); | ||
} | ||
} | ||
} | ||
|
||
private static void validateNameLength(final String name) { | ||
if (name.length() > MAX_NAME_LENGTH) { | ||
throw new InvalidMenuCategoryCreationException("메뉴 카테고리 이름은 " + MAX_NAME_LENGTH + "글자까지 가능합니다."); | ||
} | ||
} | ||
|
||
} |
46 changes: 46 additions & 0 deletions
46
src/main/java/camp/woowak/lab/menu/domain/MenuValidator.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
package camp.woowak.lab.menu.domain; | ||
|
||
import camp.woowak.lab.menu.exception.InvalidMenuCreationException; | ||
import camp.woowak.lab.store.domain.Store; | ||
|
||
public class MenuValidator { | ||
|
||
private static final int MAX_NAME_LENGTH = 10; | ||
|
||
public static void validate(final Store store, final MenuCategory menuCategory, final String name, | ||
final Integer price, final String imageUrl) { | ||
validateNotNull(store, menuCategory, name, price, imageUrl); | ||
validateNotBlank(name, imageUrl); | ||
validateNameLength(name); | ||
validatePriceNegative(price); | ||
} | ||
|
||
private static void validateNotNull(final Object... targets) { | ||
for (Object target : targets) { | ||
if (target == null) { | ||
throw new InvalidMenuCreationException(target + "은 Null 이 될 수 없습니다."); | ||
} | ||
} | ||
} | ||
|
||
private static void validateNotBlank(final String... targets) { | ||
for (String target : targets) { | ||
if (target.isBlank()) { | ||
throw new InvalidMenuCreationException(target + "은 빈 문자열이거나 공백 문자열이 포함될 수 없습니다."); | ||
} | ||
} | ||
} | ||
|
||
private static void validateNameLength(final String name) { | ||
if (name.length() > MAX_NAME_LENGTH) { | ||
throw new InvalidMenuCreationException("메뉴 이름은 " + MAX_NAME_LENGTH + "글자까지 가능합니다."); | ||
} | ||
} | ||
|
||
private static void validatePriceNegative(final Integer price) { | ||
if (price <= 0) { | ||
throw new InvalidMenuCreationException("메뉴의 가격은 양수만 가능합니다"); | ||
} | ||
} | ||
|
||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/camp/woowak/lab/menu/exception/InvalidMenuCategoryCreationException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package camp.woowak.lab.menu.exception; | ||
|
||
// TODO: extends CustomException | ||
public class InvalidMenuCategoryCreationException extends RuntimeException { | ||
|
||
public InvalidMenuCategoryCreationException(String message) { | ||
super(message); | ||
} | ||
|
||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/camp/woowak/lab/menu/exception/InvalidMenuCreationException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package camp.woowak.lab.menu.exception; | ||
|
||
// TODO: extends CustomException | ||
public class InvalidMenuCreationException extends RuntimeException { | ||
|
||
public InvalidMenuCreationException(String message) { | ||
super(message); | ||
} | ||
|
||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/camp/woowak/lab/menu/exception/NotFoundMenuCategoryException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package camp.woowak.lab.menu.exception; | ||
|
||
// TODO: extends CustomException | ||
public class NotFoundMenuCategoryException extends RuntimeException { | ||
|
||
public NotFoundMenuCategoryException(String message) { | ||
super(message); | ||
} | ||
|
||
} |
13 changes: 13 additions & 0 deletions
13
src/main/java/camp/woowak/lab/menu/repository/MenuCategoryRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package camp.woowak.lab.menu.repository; | ||
|
||
import java.util.Optional; | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
import camp.woowak.lab.menu.domain.MenuCategory; | ||
|
||
public interface MenuCategoryRepository extends JpaRepository<MenuCategory, Long> { | ||
|
||
Optional<MenuCategory> findByStoreIdAndName(Long storeId, String name); | ||
|
||
} |
8 changes: 8 additions & 0 deletions
8
src/main/java/camp/woowak/lab/menu/repository/MenuRepository.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package camp.woowak.lab.menu.repository; | ||
|
||
import org.springframework.data.jpa.repository.JpaRepository; | ||
|
||
import camp.woowak.lab.menu.domain.Menu; | ||
|
||
public interface MenuRepository extends JpaRepository<Menu, Long> { | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
9 changes: 9 additions & 0 deletions
9
src/main/java/camp/woowak/lab/store/exception/NotEqualsOwnerException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package camp.woowak.lab.store.exception; | ||
|
||
public class NotEqualsOwnerException extends RuntimeException { | ||
|
||
public NotEqualsOwnerException(String message) { | ||
super(message); | ||
} | ||
|
||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/camp/woowak/lab/store/exception/NotFoundStoreException.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package camp.woowak.lab.store.exception; | ||
|
||
// TODO: 404Exception 상속하도록 수정 | ||
public class NotFoundStoreException extends RuntimeException { | ||
|
||
public NotFoundStoreException(String message) { | ||
super(message); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.