-
Notifications
You must be signed in to change notification settings - Fork 0
[FEAT] : 예약 취소 API 개발 / 마이페이지 예약 조회 API 개발 #85
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
Changes from all commits
ab36031
635fe93
366a69f
a7926e5
26820c4
ae305c1
ddf5c18
dc7f6c7
8fbe74d
bc7d8c9
4958004
02dd443
fe1f3f1
b5fda31
8bc4e0f
03f56a0
950a46f
893ddb0
ccda430
e53a892
70bd0f7
a69fbb7
20be30d
d534aee
db246b5
b928fc5
75033a6
c08f621
0fa1481
48f250b
d75b40f
141143c
dab39bf
7a71cd7
f27fa21
01395e2
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 |
|---|---|---|
|
|
@@ -4,6 +4,7 @@ | |
| import com.eatsfine.eatsfine.domain.booking.dto.response.BookingResponseDTO; | ||
| import com.eatsfine.eatsfine.domain.booking.service.BookingCommandService; | ||
| import com.eatsfine.eatsfine.domain.booking.service.BookingQueryService; | ||
| import com.eatsfine.eatsfine.domain.booking.status.BookingSuccessStatus; | ||
| import com.eatsfine.eatsfine.domain.user.entity.User; | ||
| import com.eatsfine.eatsfine.domain.user.repository.UserRepository; | ||
| import com.eatsfine.eatsfine.global.apiPayload.ApiResponse; | ||
|
|
@@ -60,15 +61,42 @@ public ApiResponse<BookingResponseDTO.CreateBookingResultDTO> createBooking( | |
| return ApiResponse.onSuccess(bookingCommandService.createBooking(user, storeId, dto)); | ||
| } | ||
|
|
||
| @Operation(summary = "결제 완료 처리", | ||
| description = "결제 완료 후 결제 정보를 입력받아 예약 상태를 업데이트합니다.") | ||
| @PatchMapping("/bookings/{bookingId}/payments-confirm") | ||
| public ApiResponse<BookingResponseDTO.ConfirmPaymentResultDTO> confirmPayment( | ||
| @PathVariable Long bookingId, | ||
| @RequestBody @Valid BookingRequestDTO.PaymentConfirmDTO dto | ||
| ) { | ||
| //불필요한 api 삭제 | ||
| // @Operation(summary = "예약 완료 처리", | ||
| // description = "결제 완료 후 결제 정보를 입력받아 예약 상태를 업데이트합니다. 주의) 외부에서 이 API를 호출하지 않고 " + | ||
| // "POST /api/v1/payments/confirm API 호출 후 내부적으로 이 API의 로직을 실행합니다.") | ||
| // @PatchMapping("/bookings/{bookingId}/payments-confirm") | ||
| // public ApiResponse<BookingResponseDTO.ConfirmPaymentResultDTO> confirmPayment( | ||
| // @PathVariable Long bookingId, | ||
| // @RequestBody @Valid BookingRequestDTO.PaymentConfirmDTO dto | ||
| // ) { | ||
| // | ||
| // return ApiResponse.onSuccess(bookingCommandService.confirmPayment(bookingId,dto)); | ||
| // } | ||
|
|
||
| return ApiResponse.onSuccess(bookingCommandService.confirmPayment(bookingId,dto)); | ||
| @Operation(summary = "예약 취소", | ||
| description = "예약을 취소하고 환불을 진행합니다.") | ||
| @PatchMapping("/bookings/{bookingId}/cancel") | ||
| public ApiResponse<BookingResponseDTO.CancelBookingResultDTO> cancelBooking( | ||
| @PathVariable Long bookingId, | ||
| @RequestBody @Valid BookingRequestDTO.CancelBookingDTO dto | ||
| ) { | ||
| return ApiResponse.of(BookingSuccessStatus._BOOKING_CANCELED, | ||
| bookingCommandService.cancelBooking(bookingId, dto)); | ||
| } | ||
|
|
||
|
|
||
| @Operation(summary = "예약 내역 조회", | ||
| description = "마이페이지에서 나의 예약 내역을 조회합니다.") | ||
| @GetMapping("/users/bookings") | ||
| public ApiResponse<BookingResponseDTO.BookingPreviewListDTO> getMyBookings( | ||
| @RequestParam(name = "status", required = false) String status, | ||
| @RequestParam(name = "page", defaultValue = "1") Integer page | ||
| ) { | ||
| User user = userRepository.findById(1L).orElseThrow(); // 임시로 임의의 유저 사용 | ||
|
|
||
| // 서비스 호출 시 page - 1을 넘겨서 0-based index로 맞춰줍니다. | ||
| return ApiResponse.of(BookingSuccessStatus._BOOKING_FOUND, | ||
| bookingQueryService.getBookingList(user, status, page-1)); | ||
|
Comment on lines
+92
to
+100
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. 🧩 Analysis chain🏁 Script executed: cat -n src/main/java/com/eatsfine/eatsfine/domain/booking/controller/BookingController.java | sed -n '85,110p'Repository: Eatsfine/BE Length of output: 905 🏁 Script executed: cat -n src/main/java/com/eatsfine/eatsfine/domain/booking/controller/BookingController.java | head -50Repository: Eatsfine/BE Length of output: 2641 🏁 Script executed: rg "findById.*orElseThrow" src/main/java/com/eatsfine/eatsfine/domain/booking/controller/BookingController.java -A 2 -B 2Repository: Eatsfine/BE Length of output: 474 🏁 Script executed: rg "PageRequest" src/main/java/com/eatsfine/eatsfine/domain/booking/ -A 2 -B 2Repository: Eatsfine/BE Length of output: 1421 Resolve hardcoded user ID and add page bounds validation. Hardcoding Additionally, 🛠️ Example fix (auth retrieval left to your security layer)- User user = userRepository.findById(1L).orElseThrow(); // 임시로 임의의 유저 사용
-
- // 서비스 호출 시 page - 1을 넘겨서 0-based index로 맞춰줍니다.
+ User user = /* resolve authenticated user from security context */;
+
+ // 서비스 호출 시 page - 1을 넘겨서 0-based index로 맞춰줍니다.
+ int pageIndex = (page == null || page < 1) ? 0 : page - 1;
return ApiResponse.of(BookingSuccessStatus._BOOKING_FOUND,
- bookingQueryService.getBookingList(user, status, page-1));
+ bookingQueryService.getBookingList(user, status, pageIndex));🤖 Prompt for AI Agents |
||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,32 @@ | ||
| package com.eatsfine.eatsfine.domain.booking.converter; | ||
|
|
||
| import com.eatsfine.eatsfine.domain.booking.dto.response.BookingResponseDTO; | ||
| import com.eatsfine.eatsfine.domain.booking.entity.Booking; | ||
| import com.eatsfine.eatsfine.domain.payment.dto.response.PaymentResponseDTO; | ||
| import com.eatsfine.eatsfine.domain.store.entity.Store; | ||
|
|
||
| import java.math.BigDecimal; | ||
| import java.util.List; | ||
|
|
||
| public class BookingConverter { | ||
|
|
||
| public static BookingResponseDTO.CreateBookingResultDTO toCreateBookingResultDTO( | ||
| Booking booking, Store store, BigDecimal totalDeposit, | ||
| List<BookingResponseDTO.BookingResultTableDTO> resultTableDTOS, | ||
| PaymentResponseDTO.PaymentRequestResultDTO paymentInfo) { | ||
|
|
||
| return BookingResponseDTO.CreateBookingResultDTO.builder() | ||
| .bookingId(booking.getId()) | ||
| .storeName(store.getStoreName()) | ||
| .date(booking.getBookingDate()) | ||
| .time(booking.getBookingTime()) | ||
| .partySize(booking.getPartySize()) | ||
| .status(booking.getStatus().name()) | ||
| .totalDeposit(totalDeposit) | ||
| .createdAt(booking.getCreatedAt()) | ||
| .tables(resultTableDTOS) | ||
| .paymentId(paymentInfo.paymentId()) | ||
| .orderId(paymentInfo.orderId()) | ||
| .build(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| package com.eatsfine.eatsfine.domain.booking.entity.mapping; | ||
|
|
||
| import com.eatsfine.eatsfine.domain.booking.entity.Booking; | ||
| import com.eatsfine.eatsfine.domain.menu.entity.Menu; | ||
| import jakarta.persistence.*; | ||
| import lombok.*; | ||
|
|
||
| import java.math.BigDecimal; | ||
|
|
||
| @Entity | ||
| @NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
| @AllArgsConstructor | ||
| @Getter | ||
| @Builder | ||
| public class BookingMenu { | ||
|
|
||
| @Id @GeneratedValue(strategy = GenerationType.IDENTITY) | ||
| private Long id; | ||
|
|
||
| private Integer quantity; | ||
|
|
||
| private BigDecimal price; | ||
|
|
||
| @ManyToOne(fetch = FetchType.LAZY) | ||
| private Booking booking; | ||
|
|
||
| @ManyToOne(fetch = FetchType.LAZY) | ||
| private Menu menu; | ||
|
|
||
| public void confirmBooking(Booking booking) { | ||
| this.booking = booking; | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2,5 +2,5 @@ | |
|
|
||
| public enum BookingStatus { | ||
|
|
||
| PENDING, CONFIRMED, COMPLETED, CANCELLED, NOSHOW | ||
| PENDING, CONFIRMED, COMPLETED, CANCELED, NOSHOW | ||
|
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. Handle backward compatibility for persisted/serialized 🤖 Prompt for AI Agents |
||
| } | ||
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.
🧩 Analysis chain
🏁 Script executed:
Repository: Eatsfine/BE
Length of output: 114
🏁 Script executed:
Repository: Eatsfine/BE
Length of output: 224
🏁 Script executed:
Repository: Eatsfine/BE
Length of output: 5492
🏁 Script executed:
Repository: Eatsfine/BE
Length of output: 37
🏁 Script executed:
Repository: Eatsfine/BE
Length of output: 37
🏁 Script executed:
rg -n "cancelBooking" --type java -B 3 -A 25Repository: Eatsfine/BE
Length of output: 7449
🏁 Script executed:
Repository: Eatsfine/BE
Length of output: 8522
🏁 Script executed:
Repository: Eatsfine/BE
Length of output: 15577
Add ownership validation to cancelBooking.
The
cancelBookingmethod inBookingCommandServiceImplhas no ownership check. Any authenticated user can cancel another user's booking by knowing the booking ID. UnlikecreateBooking, which explicitly receives the authenticated user as a parameter,cancelBookingonly takesbookingIdanddto.Add user context extraction and verify that the authenticated user owns the booking before processing the cancellation, or refactor the method signature to accept the authenticated user like
createBookingdoes.🤖 Prompt for AI Agents