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 @@ -5,6 +5,8 @@
import com.sparta.tdd.domain.menu.dto.MenuResponseDto;
import com.sparta.tdd.domain.menu.service.MenuService;
import com.sparta.tdd.domain.user.enums.UserAuthority;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.Valid;
import java.util.List;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
Expand All @@ -29,6 +31,10 @@ public class MenuController {

private final MenuService menuService;

@Operation(
summary = "메뉴 목록 조회",
description = "가게의 메뉴 목록을 조회합니다. OWERN나 MASTER가 아니면 숨겨진 메뉴를 볼 수 없습니다."
)
@GetMapping("/{storeId}/menu")
public ResponseEntity<List<MenuResponseDto>> getMenus(@PathVariable UUID storeId,
@AuthenticationPrincipal UserDetailsImpl userDetails) {
Expand All @@ -37,6 +43,10 @@ public ResponseEntity<List<MenuResponseDto>> getMenus(@PathVariable UUID storeId
.body(menuService.getMenus(storeId, authority));
}

@Operation(
summary = "메뉴 상세 조회",
description = "가게의 특정 메뉴를 조회합니다. OWNER나 MASTER가 아니면 숨겨진 메뉴를 볼 수 없습니다. "
)
@GetMapping("/{storeId}/menu/{menuId}")
public ResponseEntity<MenuResponseDto> getMenu(@PathVariable UUID storeId,
@PathVariable UUID menuId,
Expand All @@ -46,16 +56,24 @@ public ResponseEntity<MenuResponseDto> getMenu(@PathVariable UUID storeId,
.body(menuService.getMenu(storeId, menuId, authority));
}

@Operation(
summary = "메뉴 등록",
description = "가게의 메뉴를 등록합니다. OWNER나 MASTER만 가능하며, 해당 가게 점주가 아니라면 예외가 발생합니다. "
)
@PreAuthorize("hasAnyRole('OWNER', 'MASTER')")
@PostMapping("/{storeId}/menu")
public ResponseEntity<MenuResponseDto> createMenu(@PathVariable UUID storeId,
@RequestBody MenuRequestDto menuRequestDto,
@Valid @RequestBody MenuRequestDto menuRequestDto,
@AuthenticationPrincipal UserDetailsImpl userDetails) {
Long userId = userDetails.getUserId();
return ResponseEntity.status(HttpStatus.CREATED)
.body(menuService.createMenu(storeId, menuRequestDto, userId));
}

@Operation(
summary = "메뉴 수정",
description = "가게의 메뉴를 수정합니다. OWNER나 MASTER만 가능하며, 해당 가게 점주가 아니라면 예외가 발생합니다. "
)
@PreAuthorize("hasAnyRole('OWNER', 'MASTER')")
@PatchMapping("/{storeId}/menu/{menuId}")
public ResponseEntity<Void> updateMenu(@PathVariable UUID storeId, @PathVariable UUID menuId,
Expand All @@ -66,6 +84,10 @@ public ResponseEntity<Void> updateMenu(@PathVariable UUID storeId, @PathVariable
return ResponseEntity.noContent().build();
}

@Operation(
summary = "메뉴 상태 변경",
description = "가게의 메뉴 상태를 변경합니다. 메뉴를 숨기거나, 공개할 수 있습니다. OWNER나 MASTER만 가능하며, 해당 가게 점주가 아니라면 예외가 발생합니다. "
)
@PreAuthorize("hasAnyRole('OWNER', 'MASTER')")
@PatchMapping("/{storeId}/menu/{menuId}/status")
public ResponseEntity<Void> updateMenuStatus(@PathVariable UUID storeId,
Expand All @@ -77,6 +99,10 @@ public ResponseEntity<Void> updateMenuStatus(@PathVariable UUID storeId,
return ResponseEntity.noContent().build();
}

@Operation(
summary = "메뉴 삭제",
description = "가게의 메뉴를 삭제합니다. OWNER나 MASTER만 가능하며, 해당 가게 점주가 아니라면 예외가 발생합니다. 메뉴는 soft delete 됩니다. "
)
@PreAuthorize("hasAnyRole('OWNER', 'MASTER')")
@DeleteMapping("/{storeId}/menu/{menuId}")
public ResponseEntity<Void> deleteMenu(@PathVariable UUID storeId, @PathVariable UUID menuId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@

import com.sparta.tdd.domain.menu.entity.Menu;
import com.sparta.tdd.domain.store.entity.Store;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Builder;

@Schema(description = "메뉴 등록 및 수정 요청 DTO")
@Builder
public record MenuRequestDto(
String name,
@Schema(description = "메뉴 설명", example = "바삭한 치킨과 신선한 야채가 들어간 버거")
@NotNull @Size(max = 20) String name,
String description,
Integer price,
@Schema(description = "가격", example = "10000")
@NotNull Integer price,
String imageUrl,
boolean useAiDescription
) {
Expand All @@ -22,7 +28,7 @@ public Menu toEntity(Store store, String description) {
.store(store)
.build();
}

public Menu toEntity(Store store) {
return Menu.builder()
.name(name)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
package com.sparta.tdd.domain.menu.dto;

import com.sparta.tdd.domain.menu.entity.Menu;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.UUID;
import lombok.Builder;

@Schema(description = "메뉴 응답 DTO")
@Builder
public record MenuResponseDto(
@Schema(description = "menu 아이디", example = "1")
UUID menuId,
@Schema(description = "메뉴명", example = "햄버거")
String name,
@Schema(description = "메뉴 설명", example = "바삭한 치킨과 신선한 야채가 들어간 버거")
String description,
@Schema(description = "가격", example = "10000")
Integer price,
@Schema(description = "메뉴 이미지 URL", example = "https://example.com/images/chicken-burger.jpg")
String imageUrl,
@Schema(description = "숨김 여부", example = "Boolean.False")
Boolean isHidden
) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ private User findUser(Long userId) {

private void validateUserOnMenu(User user, Store store) {
if (!store.isOwner(user)) {
throw new BusinessException(ErrorCode.STORE_OWNERSHIP_DENIED);
throw new BusinessException(ErrorCode.MENU_PERMISSION_DENIED);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public enum ErrorCode {
MENU_NOT_IN_STORE(HttpStatus.BAD_REQUEST, "해당 가게의 메뉴가 아닙니다."),
MENU_NOT_FOUND(HttpStatus.NOT_FOUND, "존재하지 않는 메뉴가 포함되어 있습니다."),
MENU_INVALID_INFO(HttpStatus.BAD_REQUEST, "메뉴 정보가 올바르지 않습니다."),
MENU_PERMISSION_DENIED(HttpStatus.FORBIDDEN, "해당 메뉴에 대한 권한이 없습니다."),

// REVIEW 도메인 관련
REVIEW_NOT_OWNED(HttpStatus.FORBIDDEN, "본인의 리뷰만 수정/삭제할 수 있습니다."),
Expand Down