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,7 @@
import com.sparta.tdd.domain.store.dto.StoreResponseDto;
import com.sparta.tdd.domain.store.enums.StoreCategory;
import com.sparta.tdd.domain.store.service.StoreService;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.Valid;
import java.net.URI;
import java.util.UUID;
Expand All @@ -31,6 +32,10 @@ public class StoreController {

private final StoreService storeService;

@Operation(
summary = "가게 검색",
description = "키워드, 카테고리, 페이징 정보로 가게를 검색합니다. 가게의 메뉴 정보도 함께 조회됩니다."
)
@GetMapping
public ResponseEntity<Page<StoreResponseDto>> searchStores(
@RequestParam(required = false) String keyword,
Expand All @@ -41,6 +46,10 @@ public ResponseEntity<Page<StoreResponseDto>> searchStores(
return ResponseEntity.ok(responseDto);
}

@Operation(
summary = "가게 생성",
description = "새로운 가게를 등록합니다. OWNER, MANAGER, MASTER 권한이 필요합니다."
)
@PreAuthorize("hasAnyRole('OWNER', 'MANAGER', 'MASTER')")
@PostMapping
public ResponseEntity<StoreResponseDto> createStore(
Expand All @@ -56,12 +65,23 @@ public ResponseEntity<StoreResponseDto> createStore(
.body(responseDto);
}


@Operation(
summary = "가게 조회",
description = """
스토어 ID를 통해 가게를 조회 합니다.
"""
)
@GetMapping("{storeId}")
public ResponseEntity<StoreResponseDto> getStore(@PathVariable UUID storeId) {
StoreResponseDto responseDto = storeService.getStore(storeId);
return ResponseEntity.ok(responseDto);
}

@Operation(
summary = "가게 상세 조회",
description = "스토어 ID를 통해 가게의 상세 정보를 조회합니다."
)
@PreAuthorize("hasAnyRole('OWNER', 'MANAGER', 'MASTER')")
@PatchMapping("{storeId}")
public ResponseEntity<Void> updateStore(
Expand All @@ -73,6 +93,10 @@ public ResponseEntity<Void> updateStore(
return ResponseEntity.ok().build();
}

@Operation(
summary = "가게 정보 수정",
description = "가게 정보를 수정합니다. OWNER, MANAGER, MASTER 권한이 필요합니다."
)
@PreAuthorize("hasAnyRole('OWNER', 'MANAGER', 'MASTER')")
@DeleteMapping("{storeId}")
public ResponseEntity<Void> deleteStore(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,33 @@
import com.sparta.tdd.domain.store.entity.Store;
import com.sparta.tdd.domain.store.enums.StoreCategory;
import com.sparta.tdd.domain.user.entity.User;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import lombok.Builder;

@Builder
@Schema(description = "가게 등록 요청DTO")
public record StoreRequestDto(

@NotBlank
@NotBlank(message = "가게 이름은 필수입니다.")
@Schema(description = "가게 이름", example = "홍콩반점")
String name,

@NotNull
@NotNull(message = "상점 카테고리는 필수입니다.")
@Schema(description = "상점 카테고리", implementation = StoreCategory.class)
StoreCategory category,

@Size(max = 255)
@Schema(description = "가게 설명 (최대 255자)", example = "정통 중화요리를 판매하는 홍콩반점입니다.")
String description,

@Pattern(regexp = "^(http|https)://.*$")
String imageUrl) {
@Schema(description = "상점 이미지 URL", example = "https://example.com/image.jpg")
String imageUrl
) {

public Store toEntity(User user) {
return Store.builder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,47 @@
import com.sparta.tdd.domain.store.entity.QStore;
import com.sparta.tdd.domain.store.entity.Store;
import com.sparta.tdd.domain.store.enums.StoreCategory;
import io.swagger.v3.oas.annotations.media.ArraySchema;
import io.swagger.v3.oas.annotations.media.Schema;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import lombok.Builder;

@Builder
@Schema(description = "가게 조회 응답 DTO")
public record StoreResponseDto(

@Schema(description = "가게 ID", example = "4f1ed1a0-e7dc-4f7d-a806-412e0e07bfbe")
UUID id,

@Schema(description = "가게 이름", example = "홍콩반점")
String name,

@Schema(description = "점주 이름", example = "TDD")
String ownerName,

@Schema(description = "상점 카테고리", implementation = StoreCategory.class)
StoreCategory category,

@Schema(description = "가게 설명", example = "정통 중화요리를 판매하는 홍콩반점입니다.")
String description,

@Schema(description = "상점 이미지 URL", example = "https://example.com/images/store1.jpg")
String imageUrl,

@Schema(description = "평균 평점", example = "4.5")
BigDecimal avgRating,

@Schema(description = "리뷰 개수", example = "128")
Integer reviewCount,

@Schema(description = "총 주문 수", example = "3456")
Long orderCount,

@ArraySchema(schema = @Schema(implementation = MenuWithStoreResponseDto.class),
arraySchema = @Schema(description = "가게에 등록된 메뉴 목록"))
List<MenuWithStoreResponseDto> menus
) {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
package com.sparta.tdd.domain.store.dto;

import com.sparta.tdd.domain.store.entity.Store;
import io.swagger.v3.oas.annotations.media.Schema;
import java.util.UUID;

public record StoreSimpleInfoDto(

@Schema(description = "가게 ID", example = "4f1ed1a0-e7dc-4f7d-a806-412e0e07bfbe")
UUID id,

@Schema(description = "가게 이름", example = "홍콩반점")
String storeName
) {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,9 @@
import io.swagger.v3.oas.annotations.Operation;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
Expand All @@ -25,65 +23,91 @@ public class UserController {

private final UserService userService;

// 회원 목록 조회
@Operation(
summary = "모든 유저 조회",
description = """
모든 유저의 id, username, password, nickname, authority를 조회합니다.
MANAGER나 MASTER가 아니면 조회할 수 없습니다.
""")
@GetMapping
@PreAuthorize("hasRole('ROLE_MASTER') or hasRole('ROLE_MANAGER')")
@Operation(summary = "모든 유저 조회")
@PreAuthorize("hasAnyRole('MANAGER', 'MASTER')")
public ResponseEntity<UserPageResponseDto> getAllUser(Pageable pageable) {
UserPageResponseDto users = new UserPageResponseDto(userService.getAllUsers(pageable));
return ResponseEntity.ok(users);
}

// 회원 정보 조회
@Operation(
summary = "유저 조회",
description = """
특정 유저의 id, username, password, nickname, authority를 조회합니다.
"""
)
@GetMapping("/{userId}")
@Operation(summary = "유저 식별자로 유저 조회")
public ResponseEntity<UserResponseDto> getUserByUserId(@PathVariable("userId") Long userId) {
UserResponseDto user = userService.getUserByUserId(userId);
return ResponseEntity.ok(user);
}

// 회원 닉네임 수정
@Operation(
summary = "유저 닉네임 변경",
description = """
유저의 닉네임을 변경합니다.
자신의 닉네임만 변경할 수 있습니다.
""")
@PatchMapping("/{userId}/nickname")
@Operation(summary = "유저 닉네임 변경")
public ResponseEntity<UserResponseDto> updateUserNickname(@PathVariable("userId") Long userId,
@RequestBody UserNicknameRequestDto requestDto,
@Valid @RequestBody UserNicknameRequestDto requestDto,
@AuthenticationPrincipal UserDetailsImpl userDetails) {
UserResponseDto responseDto = userService.updateUserNickname(userId, userDetails.getUserId(), requestDto);
return ResponseEntity.ok(responseDto);
}

// 회원 비밀번호 수정
@Operation(
summary = "유저 비밀번호 변경",
description = """
유저의 비밀번호를 변경합니다. 비밀번호는 8~15자의 대소문자, 숫자, 특수문자를 포함해야 합니다.
자신의 비밀번호만 변경할 수 있습니다.
""")
@PatchMapping("/{userId}/password")
@Operation(summary = "유저 비밀번호 변경")
public ResponseEntity<UserResponseDto> updateUserPassword(@PathVariable("userId") Long userId,
@Valid @RequestBody UserPasswordRequestDto requestDto,
@AuthenticationPrincipal UserDetailsImpl userDetails) {
UserResponseDto responseDto = userService.updateUserPassword(userId, userDetails.getUserId(), requestDto);
return ResponseEntity.ok(responseDto);
}

// 회원 매니저 권한 부여
@Operation(
summary = "유저 매니저 권한 부여",
description = """
유저의 권한을 매니저로 변경합니다. MASTER 권한을 가진 유저만 변경할 수 있습니다.
""")
@PatchMapping("/{userId}/authority")
@PreAuthorize("hasRole('ROLE_MASTER')")
@Operation(summary = "유저 매니저 권한 부여")
@PreAuthorize("hasRole('MASTER')")
public ResponseEntity<UserResponseDto> updateManagerAuthorityUser(@PathVariable("userId") Long userId) {
UserResponseDto responseDto = userService.grantUserManagerAuthority(userId);
return ResponseEntity.ok(responseDto);
}

// 회원 리뷰 목록 조회
@Operation(
summary = "유저 리뷰 목록 조회",
description = """
특정 유저가 작성한 리뷰 목록을 조회합니다. 삭제한 리뷰는 조회할 수 없습니다.
""")
@GetMapping("/{userId}/reviews")
@Operation(summary = "유저 리뷰 목록 조회")
public ResponseEntity<Page<ReviewResponseDto>> getUserReviewsByUserId(@PathVariable("userId") Long userId,
@PageableDefault Pageable pageable) {
Pageable pageable) {
Page<ReviewResponseDto> responseDto = userService.getPersonalReviews(userId, pageable);
return ResponseEntity.ok(responseDto);
}

@Operation(
summary = "유저 주문 목록 조회",
description = """
특정 유저가 주문한 주문 목록을 조회합니다. 삭제한 주문은 조회할 수 없습니다.
""")
@GetMapping("/{userId}/orders")
@Operation(summary = "유저 주문 목록 조회")
public ResponseEntity<Page<OrderResponseDto>> getUserOrdersByUserId(@PathVariable("userId") Long userId,
@PageableDefault Pageable pageable) {
Pageable pageable) {
Page<OrderResponseDto> responseDto = userService.getPersonalOrders(userId, pageable);
return ResponseEntity.ok(responseDto);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package com.sparta.tdd.domain.user.dto;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;

@Schema(description = "회원 닉네임 변경 요청 DTO")
public record UserNicknameRequestDto(
@NotBlank(message = "닉네임 입력은 필수입니다")
@Schema(description = "닉네임", example = "Nick")
String nickname
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;

@Schema(description = "회원 비밀번호 변경 요청 DTO")
public record UserPasswordRequestDto(
@NotBlank(message = "비밀번호는 필수입니다")
@Pattern(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
import com.sparta.tdd.domain.user.entity.User;
import java.util.Optional;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {
Expand Down