-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat : 웨이팅 생성 로직 구현 #26
Changes from 12 commits
8797651
0c38f50
585a0a8
10fd5ef
17a180d
bb6ee06
73aad85
a913f6b
503cb23
d46e1b2
b7fd664
08da02b
7df18a6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[[waiting-create]] | ||
=== 웨이팅 등록 | ||
|
||
==== HTTP Request | ||
include::{snippets}/waiting-create/http-request.adoc[] | ||
include::{snippets}/waiting-create/request-fields.adoc[] | ||
|
||
|
||
==== HTTP Response | ||
include::{snippets}/waiting-create/http-response.adoc[] | ||
include::{snippets}/waiting-create/response-fields.adoc[] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
ifndef::snippets[] | ||
:snippets: ../../build/generated-snippets | ||
endif::[] | ||
= Catch Table REST API 문서 | ||
:doctype: book | ||
:icons: font | ||
:source-highlighter: highlightjs | ||
:toc: left | ||
:toclevels: 2 | ||
:sectlinks: | ||
|
||
[[CatchTable-API]] | ||
== Waiting API | ||
|
||
include::api/album/waiting.adoc[] |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,15 +2,22 @@ | |
|
||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.HttpStatus; | ||
|
||
@Getter | ||
@RequiredArgsConstructor | ||
public enum ErrorCode { | ||
NOT_EXIST_MEMBER("존재하지 않는 아이디입니다."), | ||
NOT_EXIST_MEMBER("존재하지 않는 회원입니다."), | ||
|
||
ALREADY_PREOCCUPIED_RESERVATION_TIME("이미 타인에게 선점권이 있는 예약시간입니다."), | ||
ALREADY_OCCUPIED_RESERVATION_TIME("이미 예약된 시간입니다."), | ||
NOT_EXIST_SHOP("존재하지 않는 매장입니다."), | ||
NOT_EXIST_TIME("존재하지 않는 예약 시간입니다."); | ||
NOT_EXIST_TIME("존재하지 않는 예약 시간입니다."), | ||
|
||
ALREADY_CANCELED_WAITING("이미 웨이팅을 취소하였습니다."), | ||
EXISTING_MEMBER_WAITING("이미 회원이 웨이팅 중인 가게가 존재합니다."), | ||
SHOP_NOT_RUNNING("가게가 영업시간이 아닙니다."), | ||
INTERNAL_SERVER_ERROR("내부 서버 오류입니다."); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 서버에러 메세지는 어떤 경우에 쓰일까요?? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ExceptionHandler 구현 시 기타 Exception을 handling할 때 사용하려고 했습니다! |
||
|
||
private final String message; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package com.prgrms.catchtable.waiting.controller; | ||
|
||
import com.prgrms.catchtable.waiting.dto.CreateWaitingRequest; | ||
import com.prgrms.catchtable.waiting.dto.CreateWaitingResponse; | ||
import com.prgrms.catchtable.waiting.service.WaitingService; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.PathVariable; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RequestMapping; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RequiredArgsConstructor | ||
@RequestMapping("/waitings") | ||
@RestController | ||
public class WaitingController { | ||
|
||
private final WaitingService waitingService; | ||
|
||
@PostMapping("/{shopId}") | ||
public ResponseEntity<CreateWaitingResponse> createWaiting(@PathVariable("shopId") Long shopId, | ||
@RequestBody CreateWaitingRequest request) { | ||
CreateWaitingResponse response = waitingService.createWaiting(shopId, request); | ||
return ResponseEntity.ok(response); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package com.prgrms.catchtable.waiting.domain; | ||
|
||
import lombok.Getter; | ||
import lombok.RequiredArgsConstructor; | ||
@Getter | ||
@RequiredArgsConstructor | ||
public enum WaitingStatus { | ||
PROGRESS("웨이팅 진행 중"), | ||
COMPLETED("웨이팅 입장"), | ||
CANCELED("웨이팅 취소"), | ||
NO_SHOW("노쇼"); | ||
|
||
private final String description; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.prgrms.catchtable.waiting.dto; | ||
|
||
import jakarta.validation.constraints.Positive; | ||
import lombok.Builder; | ||
|
||
@Builder | ||
public record CreateWaitingRequest( | ||
@Positive(message = "인원은 1명 이상이어야 합니다.") | ||
int peopleCount | ||
){} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.prgrms.catchtable.waiting.dto; | ||
|
||
import lombok.Builder; | ||
|
||
@Builder | ||
public record CreateWaitingResponse( | ||
Long createdWaitingId, | ||
Long shopId, | ||
String shopName, | ||
int peopleCount, | ||
int waitingNumber, | ||
int waitingOrder | ||
Comment on lines
+11
to
+12
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. api 스펙 바뀐것은 pr 내용에도 넣어주시면 감사하겠습니다! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. PR 수정했습니다~ |
||
){} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package com.prgrms.catchtable.waiting.dto; | ||
|
||
import static lombok.AccessLevel.PRIVATE; | ||
|
||
import com.prgrms.catchtable.member.domain.Member; | ||
import com.prgrms.catchtable.shop.domain.Shop; | ||
import com.prgrms.catchtable.waiting.domain.Waiting; | ||
import lombok.NoArgsConstructor; | ||
|
||
@NoArgsConstructor(access = PRIVATE) | ||
public class WaitingMapper { | ||
// dto -> entity | ||
public static Waiting toWaiting(CreateWaitingRequest request, int waitingNumber, int waitingOrder, Member member, Shop shop){ | ||
return Waiting.builder() | ||
.waitingNumber(waitingNumber) | ||
.waitingOrder(waitingOrder) | ||
.peopleCount(request.peopleCount()) | ||
.member(member) | ||
.shop(shop).build(); | ||
} | ||
|
||
// entity -> dto | ||
public static CreateWaitingResponse toCreateWaitingResponse(Waiting waiting){ | ||
return CreateWaitingResponse.builder() | ||
.createdWaitingId(waiting.getId()) | ||
.shopId(waiting.getShop().getId()) | ||
.shopName(waiting.getShop().getName()) | ||
.peopleCount(waiting.getPeopleCount()) | ||
.waitingNumber(waiting.getWaitingNumber()) | ||
.waitingOrder(waiting.getWaitingOrder()) | ||
.build(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package com.prgrms.catchtable.waiting.facade; | ||
|
||
import static com.prgrms.catchtable.common.exception.ErrorCode.NOT_EXIST_MEMBER; | ||
import static com.prgrms.catchtable.common.exception.ErrorCode.NOT_EXIST_SHOP; | ||
|
||
import com.prgrms.catchtable.common.exception.custom.NotFoundCustomException; | ||
import com.prgrms.catchtable.member.domain.Member; | ||
import com.prgrms.catchtable.member.repository.MemberRepository; | ||
import com.prgrms.catchtable.shop.domain.Shop; | ||
import com.prgrms.catchtable.shop.repository.ShopRepository; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Component; | ||
|
||
@RequiredArgsConstructor | ||
@Component | ||
public class WaitingFacade { | ||
private final MemberRepository memberRepository; | ||
private final ShopRepository shopRepository; | ||
|
||
public Member getMemberEntity(Long memberId){ | ||
return memberRepository.findById(memberId).orElseThrow( | ||
()-> new NotFoundCustomException(NOT_EXIST_MEMBER) | ||
); | ||
} | ||
|
||
public Shop getShopEntity(Long shopId){ | ||
return shopRepository.findById(shopId).orElseThrow( | ||
() -> new NotFoundCustomException(NOT_EXIST_SHOP) | ||
); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 퍼사드 클래스인데 각 메소드에서 존재여부만 파악해서 여러 로직을 조립하는 과정이 없는데 퍼사드인 이유가 있을까요?? 즉, 퍼사드를 사용하는 측에서 shop의 존재여부를 알고 싶어 호출을 하면 여기선 하위 시스템들을 호출, 조립하여 응답을 하는게 아니라 여기서도 존재여부 결과만 리턴해주는 것 같습니다! |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,17 @@ | ||
package com.prgrms.catchtable.waiting.repository; | ||
|
||
import com.prgrms.catchtable.member.domain.Member; | ||
import com.prgrms.catchtable.shop.domain.Shop; | ||
import com.prgrms.catchtable.waiting.domain.Waiting; | ||
import com.prgrms.catchtable.waiting.domain.WaitingStatus; | ||
import java.time.LocalDate; | ||
import java.time.LocalDateTime; | ||
import org.springframework.data.jpa.repository.JpaRepository; | ||
import org.springframework.data.jpa.repository.Query; | ||
import org.springframework.data.repository.query.Param; | ||
|
||
public interface WaitingRepository extends JpaRepository<Waiting, Long> { | ||
|
||
boolean existsByMember(Member member); | ||
Long countByShopAndStatusAndCreatedAtBetween(Shop shop, WaitingStatus status, LocalDateTime start, LocalDateTime end); | ||
Long countByShopAndCreatedAtBetween(Shop shop, LocalDateTime start, LocalDateTime end); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package com.prgrms.catchtable.waiting.service; | ||
|
||
import static com.prgrms.catchtable.common.exception.ErrorCode.EXISTING_MEMBER_WAITING; | ||
import static com.prgrms.catchtable.waiting.domain.WaitingStatus.PROGRESS; | ||
|
||
import com.prgrms.catchtable.common.exception.custom.BadRequestCustomException; | ||
import com.prgrms.catchtable.member.domain.Member; | ||
import com.prgrms.catchtable.shop.domain.Shop; | ||
import com.prgrms.catchtable.waiting.domain.Waiting; | ||
import com.prgrms.catchtable.waiting.dto.CreateWaitingRequest; | ||
import com.prgrms.catchtable.waiting.dto.CreateWaitingResponse; | ||
import com.prgrms.catchtable.waiting.dto.WaitingMapper; | ||
import com.prgrms.catchtable.waiting.facade.WaitingFacade; | ||
import com.prgrms.catchtable.waiting.repository.WaitingRepository; | ||
import java.time.LocalDate; | ||
import java.time.LocalDateTime; | ||
import java.time.LocalTime; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
|
||
@RequiredArgsConstructor | ||
@Service | ||
public class WaitingService { | ||
private final LocalDateTime START_DATE_TIME = LocalDateTime.of(LocalDate.now(), LocalTime.of(0,0,0)); | ||
private final LocalDateTime END_DATE_TIME = LocalDateTime.of(LocalDate.now(), LocalTime.of(23,59,59)); | ||
private final WaitingRepository waitingRepository; | ||
private final WaitingFacade waitingFacade; | ||
public CreateWaitingResponse createWaiting(Long shopId, CreateWaitingRequest request) { | ||
// 연관 엔티티 조회 | ||
Member member = waitingFacade.getMemberEntity(1L); | ||
Shop shop = waitingFacade.getShopEntity(shopId); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분에서 퍼사드를 사용하는 부분이 같은 클래스내에서 로직을 메소드로 따로 빼는거랑 어떤 차이가 있는건지 잘 모르겠습니다! |
||
|
||
// shop 영업 중인지 검증 | ||
shop.validateIfShopOpened(LocalTime.now()); | ||
|
||
// 기존 waiting이 있는지 검증 | ||
validateIfMemberWaitingExists(member); | ||
|
||
// 대기 번호 생성 | ||
int waitingNumber = (waitingRepository.countByShopAndStatusAndCreatedAtBetween(shop, | ||
PROGRESS, START_DATE_TIME, END_DATE_TIME)).intValue()+1; | ||
|
||
// 대기 순서 생성 | ||
int waitingOrder = (waitingRepository.countByShopAndCreatedAtBetween(shop, | ||
START_DATE_TIME, END_DATE_TIME)).intValue()+1; | ||
|
||
// waiting 저장 | ||
Waiting waiting = WaitingMapper.toWaiting(request, waitingNumber, waitingOrder, member, shop); | ||
Waiting savedWaiting = waitingRepository.save(waiting); | ||
|
||
return WaitingMapper.toCreateWaitingResponse(savedWaiting); | ||
} | ||
|
||
private void validateIfMemberWaitingExists(Member member) { | ||
if (waitingRepository.existsByMember(member)){ | ||
throw new BadRequestCustomException(EXISTING_MEMBER_WAITING); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
단순 변수명 변경이기에, 커밋 유형이 style이면 어떨까 싶습니다~