개발일기
step2:) 요구사항 설계 작성 DDD 세레나데 본문
코드를 작성하여 돌아가는 코드를 만드는 것 또한 굉장히 중요하다. 하지만 나는 코드를 작성하여 돌아가는 코드도 중요하지만, 견고한 설계및 요구 사항을 작성하여 견고한 코드를 작성하는 것이 가장 중요하다고 점점 코딩을 하면 할 수록 느낀다.
아래는 next-step DDD 세레나데를 수강하며 http 메서드 분석을 통하여 작성한 요구사항 설계이다.
menu-group http 메서드
###
POST {{host}}/api/menu-groups
Content-Type: application/json
{
"name": "추천메뉴"
}
###
GET {{host}}/api/menu-groups
menus http 메서드
###
POST {{host}}/api/menus
Content-Type: application/json
{
"name": "후라이드+후라이드",
"price": 19000,
"menuGroupId": "f1860abc-2ea1-411b-bd4a-baa44f0d5580",
"displayed": true,
"menuProducts": [
{
"productId": "3b528244-34f7-406b-bb7e-690912f66b10",
"quantity": 2
}
]
}
###
PUT {{host}}/api/menus/f59b1e1c-b145-440a-aa6f-6095a0e2d63b/price
Content-Type: application/json
{
"price": 15000
}
###
PUT {{host}}/api/menus/f59b1e1c-b145-440a-aa6f-6095a0e2d63b/display
###
PUT {{host}}/api/menus/f59b1e1c-b145-440a-aa6f-6095a0e2d63b/hide
###
GET {{host}}/api/menus
order-tables http 메서드
###
POST {{host}}/api/order-tables
Content-Type: application/json
{
"name": "9번"
}
###
PUT {{host}}/api/order-tables/8d710043-29b6-420e-8452-233f5a035520/sit
###
PUT {{host}}/api/order-tables/8d710043-29b6-420e-8452-233f5a035520/clear
###
PUT {{host}}/api/order-tables/8d710043-29b6-420e-8452-233f5a035520/number-of-guests
Content-Type: application/json
{
"numberOfGuests": 4
}
###
GET {{host}}/api/order-tables
Orders http 메서드
###
POST {{host}}/api/orders
Content-Type: application/json
{
"type": "EAT_IN",
"orderTableId": "8d710043-29b6-420e-8452-233f5a035520",
"orderLineItems": [
{
"menuId": "f59b1e1c-b145-440a-aa6f-6095a0e2d63b",
"price": 16000,
"quantity": 3
}
]
}
###
PUT {{host}}/api/orders/69d78f38-3bff-457c-bb72-26319c985fd8/accept
###
PUT {{host}}/api/orders/69d78f38-3bff-457c-bb72-26319c985fd8/serve
###
PUT {{host}}/api/orders/69d78f38-3bff-457c-bb72-26319c985fd8/start-delivery
###
PUT {{host}}/api/orders/69d78f38-3bff-457c-bb72-26319c985fd8/complete-delivery
###
PUT {{host}}/api/orders/69d78f38-3bff-457c-bb72-26319c985fd8/complete
###
GET {{host}}/api/orders
Product http 메서드
###
POST {{host}}/api/products
Content-Type: application/json
{
"name": "강정치킨",
"price": 17000
}
###
PUT {{host}}/api/products/3b528244-34f7-406b-bb7e-690912f66b10/price
Content-Type: application/json
{
"price": 18000
}
###
GET {{host}}/api/products
요구사항 설계서
## 요구 사항
- 식당에서 음식 주문을 받는 서비스를 구현한다.
### 메뉴(Menu) : 현재 판매될 수 있는 상품의 묶음
- [ ] 메뉴를 생성한다.
- [ ] 각 메뉴는 1개의 메뉴 그룹을 반드시 가져야 한다.
- [ ] 각 메뉴는 1개 이상의 메뉴 상품을 반드시 포함해야 하며, 해당 메뉴 상품들은 이미 등록된 상품이어야 한다.
- [ ] 각 메뉴는 고유한 **UUID** 를 가져야 한다.
- [ ] 메뉴의 **가격(price)** 은 필수로 입력되어야 하며, 0 이상의 양수 값이어야 한다.
- [ ] 메뉴의 **이름(name)** 은 필수로 입력되어야 하며, 비속어가 포함되어서는 안 된다.
- [ ] 메뉴를 조회한다.
- [ ] 모든 메뉴를 조회할 수 있어야 한다.
- [ ] 특정 **UUID** 를 기반으로 메뉴를 조회할 수 있어야 한다.
- [ ] 메뉴를 수정한다.
- 메뉴 가격을 변경할 수 있어야 한다.
- 변경되는 **가격(price)** 은 0 이상의 양수이어야 한다.
- 변경된 **가격(price)** 은 메뉴 상품 가격 합보다 클 수 없어야 한다.
- 메뉴의 화면 표시 여부를 변경할 수 있어야 한다.
- [ ] 메뉴 가격이 메뉴 상품 가격 합보다 큰 경우, 표시 상태로 변경할 수 없어야 한다.
### 메뉴 그룹 (MenuGroup) : 판매되는 메뉴의 상위 분류 값
- [ ] 메뉴 그룹을 생성한다.
- [ ] 각 메뉴 그룹은 고유한 **UUID** 를 갖는다.
- [ ] 메뉴 그룹의 **이름(name)** 은 필수 입력 항목이다.
- [ ] 메뉴 그룹을 조회한다.
- [ ] 모든 메뉴 그룹을 조회할 수 있어야 한다.
### 상품 (Product) : 판매되는 상품
- [ ] 상품을 생성한다.
- [ ] **가격(price)** 은 0 이상의 양수이어야 한다.
- [ ] **이름(name)** 은 필수 입력 항목이어야 하며, 비속어가 포함되어서는 안 된다.
- [ ] 상품을 조회한다.
- [ ] 모든 상품 목록을 조회할 수 있어야 한다.
- [ ] 상품 가격을 변경한다.
- [ ] 변경되는 **가격(price)** 역시 0 이상의 양수이어야 한다.
- [ ] 가격 변경 후, 해당 상품이 포함된 모든 메뉴의 상품 가격 합계를 재계산해야 한다.
- [ ] 해당 메뉴의 상품 가격 합이 메뉴 가격보다 클 경우, 해당 메뉴를 비활성화(표시 안 함) 처리해야 한다.
### 주문 (Order) : 사용자가 주문한 상품 목록
- [ ] 주문은 총 6가지 상태가 존재한다.
- **WAITING (준비)** : 주문이 생성된 초기 상태.
- **ACCEPTED (수락됨)** : 주문이 수락된 상태.
- **SERVED (서빙됨)** : 주문 내역이 고객에게 제공된 상태.
- **DELIVERING (배달중)** : 주문이 배달 중인 상태.
- **DELIVERED (배달완료)** : 주문이 고객에게 최종적으로 전달된 상태.
- **COMPLETED (완료)** : 모든 처리가 끝난 완료 상태.
- [ ] 주문을 생성한다.
- [ ] 주문은 3가지 타입이 존재하며, 타입 필드는 필수이다.
- [ ] 주문 내역이 반드시 포함되어야 한다.
- [ ] 주문 내역은 최소 1개 이상의 주문 **항목(OrderLineItem)** 으로 구성된다.
- 각 주문 항목에 대해 다음 조건이 검증된다:
- [ ] 메뉴가 활성화 상태여야 한다.
- [ ] 주문 항목에 입력된 가격이 실제 메뉴 가격과 동일해야 한다.
- [ ] 주문 항목의 수량이 0 이상이어야 한다.
- 주문 생성 절차
- [ ] 주문이 정상적으로 생성되면, 주문 상태는 **WAITING(준비)** 으로 설정된다.
- [ ] 주문 생성 시간은 모든 검증이 완료된 후 자동으로 설정된다.
- **배달 (DELIVERY)**
- [ ] 배송지 주소가 반드시 입력되어야 한다.
- [ ] 입력된 배송지 주소가 유효한 경우에만 주문이 생성 가능하다.
- **포장 (TAKEOUT)**
- [ ] 배송지나 식사 테이블이 필요하지 않다.
- **매장 식사 (EAT_IN)**
- [ ] 유효한 식사 테이블이 할당되어 있어야 한다.
- [ ] 식사 테이블은 반드시 사용 가능한 상태여야 한다.
- [ ] 주문 상태를 변경한다.
- **주문 수락 (ACCEPTED)**
- [ ] 주문 상태가 **WAITING** 일 때만 변경한다.
- 주문 타입이 **배달(DELIVERY)** 인 경우:
- [ ] 주문의 총 금액을 계산하여 배달 라이더 클라이언트로 요청을 보낸다.
- [ ] 요청에는 **주문 ID**, **총 금액**, **배달지 주소** 가 포함된다.
- **주문 서빙 (SERVED)**
- [ ] 주문 상태가 **주문 수락(ACCEPTED)** 일 때만 변경한다.
- **배달 시작 (DELIVERING)**
- [ ] 주문 타입이 **배달(DELIVERY)** 여야 한다.
- [ ] 주문 상태가 **주문 서빙(SERVED)** 일 때만 변경한다.
- **주문 완료 (COMPLETED)**
- 주문 타입이 **배달(DELIVERY)** 인 경우:
- [ ] 상태가 **배달 완료(DELIVERED)** 여야 한다.
- 주문 타입이 **포장(TAKEOUT)** 인 경우:
- [ ] 상태가 **주문 서빙(SERVED)** 여야 한다.
- 주문 타입이 **매장 식사(EAT_IN)** 인 경우:
- [ ] 상태가 **주문 서빙(SERVED)** 여야 한다.
- [ ] 해당 테이블의 모든 주문이 **주문 완료(COMPLETED)** 상태일 경우, 테이블을 초기화한다.
- [ ] 테이블의 손님 수를 0으로 설정하고, **비어있음(occupied = false)** 상태로 변경한다.
### 주문 항목 (OrderLineItem) : 각 주문에 대한 세부 사항
- 각 주문 항목은 다음 정보를 포함한다:
- [ ] 해당 주문 항목에 대한 메뉴 식별자는 필수이다.
- [ ] 주문한 메뉴의 개수는 0 이상이어야 한다.
- [ ] 주문 항목의 가격은 실제 메뉴 가격과 일치해야 한다.
### 주문 테이블 (OrderTable) : 매장 내 식사를 위한 테이블
- [ ] 주문 테이블을 생성한다.
- [ ] **이름(name)** 은 필수이다.
- [ ] **테이블 손님 수(numberOfGuests)** 를 0으로 초기화한다.
- [ ] **테이블 사용 여부(occupied)** 는 **미사용(false)** 으로 설정한다.
- [ ] 주문 테이블 사용 여부를 변경한다.
- [ ] 주문 테이블의 사용 여부를 **사용 중(true)** 으로 변경할 수 있다.
- [ ] 주문 테이블을 초기화한다.
- [ ] 테이블에 속한 **주문의 상태가 완료(COMPLETED)** 일 때만 초기화 할 수 있다.
- [ ] 테이블 **손님 수(numberOfGuests)** 를 0 으로 지정한다.
- [ ] 테이블 **사용 여부(occupied)** 를 **미사용(false)** 으로 재설정한다.
- [ ] 주문 테이블의 손님 수를 변경한다.
- [ ] 변경되는 손님 수는 0 이상이어야 한다.
- [ ] 테이블이 **사용 중(true)** 일 때만 손님 수를 변경할 수 있다.
이미 작성된 레거시 프로그램의 Service, Controller, Domain 코드를 통하여 작성한 요구사항 설계서이다.
'DDD' 카테고리의 다른 글
레이어드 형식 패키지 -> DDD형식 패키지로 변경 (0) | 2025.03.22 |
---|---|
step3) 1편 DDD 세레나데 테스트를 통한 코드 보호 (0) | 2025.02.05 |
[기획 & 설계] 이벤트 스토밍 (Event Stroming) (0) | 2025.01.11 |
유비쿼터스 언어(보편 언어)의 중요성 (0) | 2025.01.11 |
[개발 & 방법론 / DDD] 바운디드 컨텍스트 (BOUNDED CONTEXT) (0) | 2025.01.10 |