Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
import com.sparta.deliveryi.order.domain.service.OrderCreator;
import com.sparta.deliveryi.order.domain.service.OrderFinder;
import com.sparta.deliveryi.order.domain.service.OrderManager;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
Expand All @@ -24,6 +28,11 @@
import static com.sparta.deliveryi.global.presentation.dto.ApiResponse.successWithDataOnly;
import static org.springframework.http.ResponseEntity.ok;

@Tag(name = "주문 API", description = """
주문 요청(Order Requested)부터 주문 완료(Order Completed)까지의 주문 처리 단계 관련 기능 제공.
- 주문 생성 / 조회 / 취소
- 주문 수락 / 거절 / 조리 완료 / 배달 시작 / 주문 완료
""")
@RestController
@RequiredArgsConstructor
public class OrderApi {
Expand All @@ -36,6 +45,13 @@ public class OrderApi {

private final OrderApplication orderApplication;

@Operation(
summary = "주문 요청 (Order Requested)",
description = """
고객이 신규 주문을 생성합니다.
주문 생성 시 상태는 기본적으로 '주문 요청(Order Requested)'으로 설정됩니다.
"""
)
@PreAuthorize("hasAnyRole('CUSTOMER', 'OWNER', 'MANAGER', 'MASTER')")
@PostMapping("/v1/orders")
public ResponseEntity<ApiResponse<OrderCreateResponse>> create(@RequestBody @Valid OrderCreateRequest createRequest) {
Expand All @@ -44,10 +60,16 @@ public ResponseEntity<ApiResponse<OrderCreateResponse>> create(@RequestBody @Val
return ok(ApiResponse.successWithDataOnly(OrderCreateResponse.from(order)));
}

@Operation(
summary = "주문 검색",
description = "상점 및 주문자 기준으로 주문 목록을 조회합니다."
)
@PreAuthorize("hasAnyRole('CUSTOMER', 'OWNER', 'MANAGER', 'MASTER')")
@GetMapping("/v1/orders")
public ResponseEntity<ApiResponse<Page<OrderSearchResponse>>> search(
@Parameter(name = "storeId", description = "가게 ID (UUID)", in = ParameterIn.QUERY, required = true)
@RequestParam UUID storeId,
@Parameter(name = "ordererId", description = "주문자 ID (UUID)", in = ParameterIn.QUERY, required = true)
@RequestParam UUID ordererId,
@PageableDefault(sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable
) {
Expand All @@ -59,10 +81,17 @@ public ResponseEntity<ApiResponse<Page<OrderSearchResponse>>> search(
return ok(successWithDataOnly(responses));
}

@Operation(
summary = "배달 주소 변경",
description = """
주문 수락(Order Accepted) 상태 이전의 주문에 대해 배달 주소를 수정합니다.
"""
)
@PreAuthorize("hasAnyRole('CUSTOMER', 'OWNER', 'MANAGER', 'MASTER')")
@PutMapping("/v1/orders/{orderId}/delivery-address")
public ResponseEntity<ApiResponse<ChangeDeliveryAddressResponse>> changeDeliveryAddress(
@AuthenticationPrincipal Jwt jwt,
@Parameter(name = "orderId", description = "주문 ID (UUID)", in = ParameterIn.PATH, required = true)
@PathVariable UUID orderId,
@RequestBody @Valid ChangeDeliveryAddressRequest changeRequest
) {
Expand All @@ -72,59 +101,125 @@ public ResponseEntity<ApiResponse<ChangeDeliveryAddressResponse>> changeDelivery
return ok(ApiResponse.successWithDataOnly(ChangeDeliveryAddressResponse.from(order)));
}

@Operation(
summary = "주문 수락 (Order Accepted)",
description = """
주문을 수락합니다.
주문 상태가 '주문 수락(Order Accepted)'으로 변경됩니다.
"""
)
@PreAuthorize("hasAnyRole('OWNER', 'MANAGER', 'MASTER')")
@PostMapping("/v1/orders/{orderId}/accept")
public ResponseEntity<ApiResponse<Void>> accept(@AuthenticationPrincipal Jwt jwt, @PathVariable UUID orderId) {
public ResponseEntity<ApiResponse<Void>> accept(
@AuthenticationPrincipal Jwt jwt,
@Parameter(name = "orderId", description = "주문 ID (UUID)", in = ParameterIn.PATH, required = true)
@PathVariable UUID orderId
) {
UUID requestId = UUID.fromString(jwt.getSubject());

orderApplication.accept(orderId, requestId);

return ok(success());
}

@Operation(
summary = "주문 거절 (Order Rejected)",
description = """
주문을 거절합니다.
주문 상태가 '주문 거절(Order Rejected)'로 변경됩니다.
"""
)
@PreAuthorize("hasAnyRole('OWNER', 'MANAGER', 'MASTER')")
@PostMapping("/v1/orders/{orderId}/reject")
public ResponseEntity<ApiResponse<Void>> reject(@AuthenticationPrincipal Jwt jwt, @PathVariable UUID orderId) {
public ResponseEntity<ApiResponse<Void>> reject(
@AuthenticationPrincipal Jwt jwt,
@Parameter(name = "orderId", description = "주문 ID (UUID)", in = ParameterIn.PATH, required = true)
@PathVariable UUID orderId
) {
UUID requestId = UUID.fromString(jwt.getSubject());

orderApplication.reject(orderId, requestId);

return ok(success());
}

@Operation(
summary = "주문 취소 (Order Canceled)",
description = """
주문을 취소합니다.
주문 상태가 '주문 취소(Order Canceled)'로 변경됩니다.
"""
)
@PreAuthorize("hasAnyRole('CUSTOMER', 'OWNER', 'MANAGER', 'MASTER')")
@PostMapping("/v1/orders/{orderId}/cancel")
public ResponseEntity<ApiResponse<Void>> cancel(@AuthenticationPrincipal Jwt jwt, @PathVariable UUID orderId) {
public ResponseEntity<ApiResponse<Void>> cancel(
@AuthenticationPrincipal Jwt jwt,
@Parameter(name = "orderId", description = "주문 ID (UUID)", in = ParameterIn.PATH, required = true)
@PathVariable UUID orderId
) {
UUID requestId = UUID.fromString(jwt.getSubject());

orderManager.cancel(OrderId.of(orderId), requestId);

return ok(success());
}

@Operation(
summary = "조리 완료 (Ready To Served)",
description = """
점주(OWNER) 또는 관리자(MANAGER/MASTER)가 조리가 완료되었음을 알립니다.
주문 상태가 '주문 수락(Order Accepted)' → '조리 완료(Ready To Served)'로 변경됩니다.
"""
)
@PreAuthorize("hasAnyRole('OWNER', 'MANAGER', 'MASTER')")
@PostMapping("/v1/orders/{orderId}/complete-cooking")
public ResponseEntity<ApiResponse<Void>> completeCooking(@AuthenticationPrincipal Jwt jwt, @PathVariable UUID orderId) {
public ResponseEntity<ApiResponse<Void>> completeCooking(
@AuthenticationPrincipal Jwt jwt,
@Parameter(name = "orderId", description = "주문 ID (UUID)", in = ParameterIn.PATH, required = true)
@PathVariable UUID orderId
) {
UUID requestId = UUID.fromString(jwt.getSubject());

orderApplication.completeCooking(orderId, requestId);

return ok(success());
}

@Operation(
summary = "배달 중 (Delivering)",
description = """
점주(OWNER) 또는 관리자(MANAGER/MASTER)가 배달을 시작합니다.
주문 상태가 '조리 완료(Ready To Served)' → '배달 중(Delivering)'으로 변경됩니다.
"""
)
@PreAuthorize("hasAnyRole('OWNER', 'MANAGER', 'MASTER')")
@PostMapping("/v1/orders/{orderId}/delivery")
public ResponseEntity<ApiResponse<Void>> delivery(@AuthenticationPrincipal Jwt jwt, @PathVariable UUID orderId) {
public ResponseEntity<ApiResponse<Void>> delivery(
@AuthenticationPrincipal Jwt jwt,
@Parameter(name = "orderId", description = "주문 ID (UUID)", in = ParameterIn.PATH, required = true)
@PathVariable UUID orderId
) {
UUID requestId = UUID.fromString(jwt.getSubject());

orderApplication.delivery(orderId, requestId);

return ok(success());
}

@Operation(
summary = "주문 완료 (Order Completed)",
description = """
배달이 완료되어 주문을 마무리합니다.
주문 상태가 '배달 중(Delivering)' → '주문 완료(Order Completed)'으로 변경됩니다.
"""
)
@PreAuthorize("hasAnyRole('OWNER', 'MANAGER', 'MASTER')")
@PostMapping("/v1/orders/{orderId}/complete")
public ResponseEntity<ApiResponse<Void>> complete(@AuthenticationPrincipal Jwt jwt, @PathVariable UUID orderId) {
public ResponseEntity<ApiResponse<Void>> complete(
@AuthenticationPrincipal Jwt jwt,
@Parameter(name = "orderId", description = "주문 ID (UUID)", in = ParameterIn.PATH, required = true)
@PathVariable UUID orderId
) {
UUID requestId = UUID.fromString(jwt.getSubject());

orderApplication.complete(orderId, requestId);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import com.sparta.deliveryi.review.domain.Review;
import com.sparta.deliveryi.review.domain.ReviewRegisterRequest;
import com.sparta.deliveryi.review.domain.ReviewUpdateRequest;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
Expand All @@ -22,12 +25,14 @@
import static com.sparta.deliveryi.global.presentation.dto.ApiResponse.successWithDataOnly;
import static org.springframework.http.ResponseEntity.ok;

@Tag(name = "리뷰 API", description = "리뷰 등록, 조회, 수정, 삭제 관련 API 제공")
@RestController
@RequiredArgsConstructor
public class ReviewApi {

private final ReviewApplication reviewApplication;

@Operation(summary = "리뷰 등록", description = "가게에 대한 리뷰를 등록합니다.")
@PreAuthorize("hasAnyRole('CUSTOMER', 'OWNER', 'MANAGER', 'MASTER')")
@PostMapping("/v1/reviews")
public ResponseEntity<ApiResponse<ReviewRegisterResponse>> register(
Expand All @@ -41,12 +46,16 @@ public ResponseEntity<ApiResponse<ReviewRegisterResponse>> register(
return ok(successWithDataOnly(ReviewRegisterResponse.from(review)));
}

@Operation(summary = "리뷰 목록 조회", description = "가게 및 작성자 기준으로 검색하거나 키워드로 필터링합니다.")
@PreAuthorize("hasAnyRole('CUSTOMER', 'OWNER', 'MANAGER', 'MASTER')")
@GetMapping("/v1/reviews")
public ResponseEntity<ApiResponse<Page<ReviewSearchResponse>>> search(
@AuthenticationPrincipal Jwt jwt,
@Parameter(description = "스토어 ID", required = true)
@RequestParam UUID storeId,
@Parameter(description = "리뷰 작성자 ID", required = true)
@RequestParam UUID reviewerId,
@Parameter(description = "리뷰 내용 검색 키워드")
@RequestParam String keyword,
@PageableDefault(sort = "createdAt", direction = Sort.Direction.DESC) Pageable pageable
) {
Expand All @@ -59,10 +68,12 @@ public ResponseEntity<ApiResponse<Page<ReviewSearchResponse>>> search(
return ok(successWithDataOnly(responses));
}

@Operation(summary = "리뷰 수정", description = "작성한 리뷰를 수정합니다.")
@PreAuthorize("hasAnyRole('CUSTOMER', 'OWNER', 'MANAGER', 'MASTER')")
@PutMapping("/v1/reviews/{reviewId}")
public ResponseEntity<ApiResponse<ReviewUpdateResponse>> update(
@AuthenticationPrincipal Jwt jwt,
@Parameter(description = "리뷰 ID", required = true)
@PathVariable Long reviewId,
@RequestBody @Valid ReviewUpdateRequest updateRequest
) {
Expand All @@ -73,11 +84,14 @@ public ResponseEntity<ApiResponse<ReviewUpdateResponse>> update(
return ok(successWithDataOnly(ReviewUpdateResponse.from(order)));
}

@Operation(summary = "리뷰 삭제", description = "사용자가 작성한 리뷰를 삭제합니다.")
@PreAuthorize("hasAnyRole('CUSTOMER', 'OWNER', 'MANAGER', 'MASTER')")
@DeleteMapping("/v1/reviews/{reviewId}")
public ResponseEntity<ApiResponse<ReviewRemoveResponse>> remove(
@AuthenticationPrincipal Jwt jwt,
@PathVariable Long reviewId) {
@Parameter(description = "리뷰 ID", required = true)
@PathVariable Long reviewId
) {
UUID requestId = UUID.fromString(jwt.getSubject());

Review review = reviewApplication.remove(reviewId, requestId);
Expand Down
Loading