우아한테크코스 웹 백엔드 4기, 레거시 코드 리팩터링 - Kitchen POS 저장소입니다.
- kitchenpos 패키지의 코드를 보고 키친포스의 요구 사항을 README.md에 작성한다.
- 미션을 진행함에 있어 이 문서를 적극 활용한다.
- 정리한 키친포스의 요구 사항을 토대로 테스트 코드를 작성한다.
- 모든 Business Object에 대한 테스트 코드를 작성한다.
- @SpringBootTest를 이용한 통합 테스트 코드 또는 @ExtendWith(MockitoExtension.class)를 이용한 단위 테스트 코드를 작성한다.
- Controller에 대한 테스트 코드 작성은 권장하지만 필수는 아니다.
- 미션을 진행함에 있어 아래 문서를 적극 활용한다.
- E2E, 서비스, 컨트롤러 테스트 구현
- RestDocs, ERD, Postman 문서화
- Request, Response DTO 도입
- 서비스 인터페이스 추상화
- 1단계 테스트를 통한 코드 보호 PR
- JdbcTempalte -> JPA 전환
- 프로덕트, 메뉴그룹 name 유니크 제약조건 제거. 기존 프로덕션 로직 및 스키마에 없는 제약조건.
- 도메인 엔티티에 유효성 검증 및 비즈니스 로직 내재화
- 2단계 서비스 리팩터링 PR
- 일급 컬렉션 도입
- 도메인 엔티티 VO 적용
- 메뉴 이름 변경 시 기존 주문 이력이 변경되지 않도록 구현
- 클래스간, 패키지 간 단방향으로 리팩터링
- 가장 많이 팔린 메뉴 조회 가능해야함
- Flyway 도입
- 메뉴 정보가 변경되더라도 주문 항목이 변경되지 않게 구현한다.
- 3단계 의존성 리팩터링 PR
- Gradle의 멀티 모듈 개념을 적용해 자유롭게 서로 다른 프로젝트로 분리해 본다.
- 로직 분석 후, E2E -> 서비스 레이어 테스트를 먼저 구현했습니다.
- RestDocs를 통한 컨트롤러 테스트와 문서화를 진행하던 도중 컨트롤러와 서비스 레이어의 의존을 분리했습니다
- 기존에는 컨트롤러에서 RequestBody로 받는 매개변수도 도메인 객체로 받고 있었습니다.
- 그로인해 레이어간 결합이 발생했고, 엔드포인트마다 어떤 데이터가 필요하고 사용되는지 파악하기 어려웠습니다.
- DTO를 도입하여 서비스 레이어 내에서 도메인 객체로 변환하여 처리하도록 구성하였습니다.
- 컨트롤러에서는 RequestDTO를 받도록 구성하여 서비스 레이어와 의존성을 분리했고, 어떤 데이터가 사용되는지 파악하기 쉬워졌습니다.
- JDBC에서 JPA 기반으로 마이그레이션 완료하였습니다.
- 프로덕트 생성과 조회가 가능하다.
- 프로덕트 생성 시
이름
과가격
을 받는다.- 유효성 검사
- 이름은 반드시 존재해야 하고, 유효한 문자가 1개 이상 존재해야 한다.
- 가격은 반드시 존재해야 하고, 0 이상이어야 한다.
- 이름은 중복될 수 없다.
- 유효성 검사
- 테이블 생성과 조회, 주문 가능 여부 수정, 고객 인원 수정이 가능하다.
- 테이블 생성 시
고객 인원 수
와,주문 가능 여부
를 받는다.- 고객 인원 수 기본값은 0이다.
- 주문 가능 여부 기본값은 주문 불가 이다.
- 유효성 검사
- 고객 인원 수는 0 이상이어야 한다.
- 테이블 주문 가능 여부 수정 시 주문 가능 여부를 받는다
- 유효성 검사
- 수정 요청한 테이블 아이디에 매칭되는 테이블이 반드시 존재해야 한다.
- 조회된 테이블에 그룹 아이디가 존재하지 않아야 한다. 즉, 단체로 묶여있는 테이블은 주문 가능 여부 수정이 불가하다.
- 조회된 테이블에 조리시작(COOKING) 또는 식사중(MEAL) 상태인 주문이 없어야 한다. 즉, 계산 완료(COMPLETION) 상태여야 수정할 수 있다.
- 유효성 검사
- 테이블 고객 인원 수정 시 고객 인원 수를 받는다
- 유효성 검사
- 고객 인원 수는 0 이상이어야 한다.
- 수정 요청한 테이블 아이디에 매칭되는 테이블이 반드시 존재해야 한다.
- 조회된 테이블이 주문 불가 상태일 경우 예외이다. 주문 불가 테이블에 대한 인원 수정 요청은 잘못된 요청이다.
- 유효성 검사
- 메뉴 생성, 조회가 가능하다.
- 메뉴 생성 시
이름
,가격
,메뉴 그룹 아이디
,메뉴 프로덕트 목록
을 받는다. 메뉴 프로덕트 목록은 프로덕트 아이디와 수량을 담은 배열이다.- 유효성 검사
- 가격은 반드시 존재해야 하고, 0 이상이어야 한다.
- 메뉴 그룹 아이디는 실재하는 유효한 아이디여야 한다. 즉, 메뉴 생성 시점부터 메뉴는 특정 메뉴 그룹에 속해야 한다.
- 메뉴 프로덕트 목록은 반드시 존재해야 하고, 1개 이상의 메뉴 프로덕트가 담겨있어야 한다.
- 메뉴 가격은 메뉴 프로덕트 목록의 총합계액 보다 클 수 없다. 즉, 낱개의 합 보다 더 비싸게 가격을 책정할 수 없다.
- 0 <= 메뉴 가격 <= 메뉴 프로덕트 목록 총합계액
- 유효성 검사
- 테이블 그룹은 테이블을 묶어서 단체 손님으로 설정하는 것을 의미한다.
- 테이블 그룹의 생성과 삭제가 가능하다.
- 테이블 그룹 생성 시 그룹화할 테이블 아이디 목록을 받는다.
- 유효성 검사
- 테이블 아이디 목록은 반드시 존재해야 하고, 2개 이상의 테이블 아이디가 존재해야 한다.
- 모든 테이블 아이디 마다 각각 매칭되는 테이블이 반드시 존재해야 한다.
- 모든 테이블이 다른 그룹에 이미 할당되어 있지 않아야 한다. 즉, 테이블 그룹 아이디가 없어야 한다.
- 모든 테이블이 주문 불가 상태 상태여야 한다.
- 테이블 그룹으로 묶여질 때 모든 테이블의 주문 가능 여부가 주문 가능으로 변경된다.
- 유효성 검사
- 테이블 그룹 삭제 시 테이블 그룹 아이디를 받는다.
- 유효성 검사
- 테이블 그룹 아이디로 조회된 모든 테이블에 조리 시작(COOKING) 또는 식사중(MEAL) 상태인 주문이 존재하지 않아야 한다
- 테이블 그룹 삭제 시 모든 테이블의 테이블 그룹아이디가 제거된다
- 유효성 검사
- 메뉴 그룹은 개별 메뉴가 소속되는 곳이다. 가령
한 마리 메뉴
라는 메뉴 그룹에후라이드 한 마리
가 속하는 식이다. - 메뉴 그룹 생성, 조회가 가능하다
- 메뉴 그룹 생성 시 이름을 받는다.
- 유효성 검사
- 이름은 반드시 존재해야 하고, 공백이 아닌 문자가 존재해야 한다.
- 이름은 중복되지 않아야 한다.
- 유효성 검사
- 주문 생성, 전체 조회, 주문 상태 수정이 가능하다
- 주문 생성 시
테이블 아이디
,주문 아이템 목록
을 받는다 주문 아이템 목록의 요소는 메뉴 아이디와 수량이다.- 유효성 검사
- 주문 아이템 목록은 반드시 존재해야 하고 하나 이상의 요소를 가지고 있어야 한다.
- 메뉴 아이템 목록 내 모든 메뉴 아이디가 실재하는 유효한 메뉴 아이디여야 한다.
- 테이블 아이디로 조회한 테이블이 주문 가능한 상태여야 한다.
- 유효성 검사
- 주문 상태 수정 시 주문 아이디와 수정하고자 하는 주문 상태값을 받는다.
- 유효성 검사
- 요청한 주문 아이디로 주문을 조회했을 때 존재하지 않으면 예외이다.
- 주문의 상태가 이미
계산 완료(COMPLETION)
상태일 경우 상태를 변경할 수 없다.
- 유효성 검사
한글명 | 영문명 | 설명 |
---|---|---|
상품 | product | 메뉴를 관리하는 기준이 되는 데이터 |
메뉴 그룹 | menu group | 메뉴 묶음, 분류 |
메뉴 | menu | 메뉴 그룹에 속하는 실제 주문 가능 단위 |
메뉴 상품 | menu product | 메뉴에 속하는 수량이 있는 상품 |
금액 | amount | 가격 * 수량 |
주문 테이블 | order table | 매장에서 주문이 발생하는 영역 |
빈 테이블 | empty table | 주문을 등록할 수 없는 주문 테이블 |
주문 | order | 매장에서 발생하는 주문 |
주문 상태 | order status | 주문은 조리 ➜ 식사 ➜ 계산 완료 순서로 진행된다. |
방문한 손님 수 | number of guests | 필수 사항은 아니며 주문은 0명으로 등록할 수 있다. |
단체 지정 | table group | 통합 계산을 위해 개별 주문 테이블을 그룹화하는 기능 |
주문 항목 | order line item | 주문에 속하는 수량이 있는 메뉴 |
매장 식사 | eat in | 포장하지 않고 매장에서 식사하는 것 |