diff --git a/src/main/java/com/example/green/domain/example/api/ExamplePostResponseMessage.java b/src/main/java/com/example/green/domain/example/api/ExamplePostResponseMessage.java deleted file mode 100644 index cbbf890c..00000000 --- a/src/main/java/com/example/green/domain/example/api/ExamplePostResponseMessage.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.example.green.domain.example.api; - -import com.example.green.global.api.ResponseMessage; - -import lombok.AllArgsConstructor; -import lombok.Getter; - -@Getter -@AllArgsConstructor -public enum ExamplePostResponseMessage implements ResponseMessage { - POST_CREATED("게시글이 생성되었습니다."), - POST_UPDATED("게시글이 수정되었습니다."), - POST_FOUND("게시글이 조회되었습니다."), - POST_DELETED("게시글이 삭제되었습니다."); - - private final String message; -} diff --git a/src/main/java/com/example/green/domain/example/controller/ExamplePostController.java b/src/main/java/com/example/green/domain/example/controller/ExamplePostController.java deleted file mode 100644 index a2479f3a..00000000 --- a/src/main/java/com/example/green/domain/example/controller/ExamplePostController.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.example.green.domain.example.controller; - -import java.time.LocalDateTime; -import java.util.List; - -import org.springframework.context.annotation.Profile; -import org.springframework.web.bind.annotation.DeleteMapping; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.PutMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; - -import com.example.green.domain.example.api.ExamplePostResponseMessage; -import com.example.green.domain.example.dto.PostListResponse; -import com.example.green.domain.example.dto.PostRequest; -import com.example.green.domain.example.dto.PostResponse; -import com.example.green.global.api.ApiTemplate; -import com.example.green.global.api.NoContent; -import com.example.green.global.security.annotation.AdminApi; -import com.example.green.global.security.annotation.AuthenticatedApi; -import com.example.green.global.security.annotation.PublicApi; - -import jakarta.validation.Valid; -import lombok.RequiredArgsConstructor; - -@Profile("test") -@RestController -@RequestMapping("/api/posts") -@RequiredArgsConstructor -public class ExamplePostController implements ExamplePostControllerDocs { - - @AuthenticatedApi(reason = "게시글 작성은 로그인한 사용자만 가능합니다") - @PostMapping - public ApiTemplate createPost(@Valid @RequestBody PostRequest request) { - PostResponse response = new PostResponse(1L, request.getTitle(), request.getContent(), "홍길동", - LocalDateTime.now()); - return ApiTemplate.ok(ExamplePostResponseMessage.POST_CREATED, response); - } - - @AuthenticatedApi(reason = "게시글 수정은 로그인한 사용자만 가능합니다") - @PutMapping("/{postId}") - public ApiTemplate updatePost(@PathVariable Long postId, @Valid @RequestBody PostRequest request) { - PostResponse response = new PostResponse(postId, request.getTitle(), request.getContent(), "홍길동", - LocalDateTime.now()); - return ApiTemplate.ok(ExamplePostResponseMessage.POST_UPDATED, response); - } - - @AdminApi(reason = "게시글 삭제는 관리자만 가능합니다") - @DeleteMapping("/{postId}") - public NoContent deletePost(@PathVariable Long postId) { - return NoContent.ok(ExamplePostResponseMessage.POST_DELETED); - } - - @PublicApi(reason = "게시글 상세 조회는 누구나 가능합니다") - @GetMapping("/{postId}") - public ApiTemplate getPostById(@PathVariable Long postId) { - PostResponse response = new PostResponse(postId, "제목 예시", "본문 예시", "홍길동", LocalDateTime.now()); - return ApiTemplate.ok(ExamplePostResponseMessage.POST_FOUND, response); - } - - @PublicApi(reason = "게시글 목록 조회는 누구나 가능합니다") - @GetMapping - public ApiTemplate getPosts(@RequestParam(defaultValue = "0") int page, - @RequestParam(defaultValue = "20") int size) { - List posts = List.of( - new PostResponse(1L, "첫 번째 글", "내용입니다", "홍길동", LocalDateTime.now()), - new PostResponse(2L, "두 번째 글", "내용입니다", "김철수", LocalDateTime.now()) - ); - PostListResponse response = new PostListResponse(posts, 10, 153, page, size); - return ApiTemplate.ok(ExamplePostResponseMessage.POST_FOUND, response); - } -} diff --git a/src/main/java/com/example/green/domain/example/controller/ExamplePostControllerDocs.java b/src/main/java/com/example/green/domain/example/controller/ExamplePostControllerDocs.java deleted file mode 100644 index b0aa509c..00000000 --- a/src/main/java/com/example/green/domain/example/controller/ExamplePostControllerDocs.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.example.green.domain.example.controller; - -import com.example.green.domain.example.dto.PostListResponse; -import com.example.green.domain.example.dto.PostRequest; -import com.example.green.domain.example.dto.PostResponse; -import com.example.green.global.api.ApiTemplate; -import com.example.green.global.api.NoContent; -import com.example.green.global.docs.ApiError400; -import com.example.green.global.docs.ApiErrorStandard; - -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.responses.ApiResponse; -import io.swagger.v3.oas.annotations.tags.Tag; - -@Tag(name = "게시글 API", description = "게시글 생성, 조회, 수정, 삭제 API") -public interface ExamplePostControllerDocs { - - @Operation(summary = "게시글 생성", description = "게시글을 생성합니다.") - @ApiErrorStandard - @ApiError400 - @ApiResponse(responseCode = "200", description = "게시글 생성 성공", useReturnTypeSchema = true) - ApiTemplate createPost(PostRequest request); - - @Operation(summary = "게시글 수정", description = "게시글 ID로 게시글을 수정합니다.") - @ApiErrorStandard - @ApiError400 - @ApiResponse(responseCode = "200", description = "게시글 수정 성공", useReturnTypeSchema = true) - ApiTemplate updatePost( - @Parameter(name = "postId", description = "수정할 게시글의 ID", - in = ParameterIn.PATH, required = true, example = "1") Long postId, - PostRequest request - ); - - @Operation(summary = "게시글 삭제", description = "게시글 ID로 게시글을 삭제합니다.") - @ApiErrorStandard - @ApiResponse(responseCode = "200", description = "게시글 삭제 성공", useReturnTypeSchema = true) - NoContent deletePost( - @Parameter(name = "postId", description = "삭제할 게시글의 ID", - in = ParameterIn.PATH, required = true, example = "1") Long postId - ); - - @Operation(summary = "게시글 조회", description = "게시글 ID로 게시글을 조회합니다.") - @ApiErrorStandard - @ApiResponse(responseCode = "200", description = "게시글 조회 성공", useReturnTypeSchema = true) - ApiTemplate getPostById( - @Parameter(name = "postId", description = "조회할 게시글의 ID", - in = ParameterIn.PATH, required = true, example = "1") Long postId - ); - - @Operation(summary = "게시글 목록 조회", description = "페이징 정보를 기준으로 게시글 목록을 조회합니다.") - @ApiErrorStandard - @ApiResponse(responseCode = "200", description = "게시글 목록 조회 성공", useReturnTypeSchema = true) - ApiTemplate getPosts( - @Parameter(name = "page", description = "조회할 페이지 번호 (0부터 시작)", example = "0", required = true) int page, - @Parameter(name = "size", description = "페이지당 게시글 수", example = "20", required = true) int size - ); -} diff --git a/src/main/java/com/example/green/domain/example/dto/PostListResponse.java b/src/main/java/com/example/green/domain/example/dto/PostListResponse.java deleted file mode 100644 index 83e8c660..00000000 --- a/src/main/java/com/example/green/domain/example/dto/PostListResponse.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.example.green.domain.example.dto; - -import java.util.List; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Getter; - -@Getter -@AllArgsConstructor -@Schema(description = "게시글 목록 응답 DTO") -public class PostListResponse { - - @Schema(description = "게시글 목록") - private List content; - - @Schema(description = "총 페이지 수", example = "10") - private int totalPages; - - @Schema(description = "전체 게시글 수", example = "153") - private long totalElements; - - @Schema(description = "현재 페이지 번호", example = "0") - private int page; - - @Schema(description = "페이지 크기", example = "20") - private int size; -} diff --git a/src/main/java/com/example/green/domain/example/dto/PostRequest.java b/src/main/java/com/example/green/domain/example/dto/PostRequest.java deleted file mode 100644 index 7c632b0a..00000000 --- a/src/main/java/com/example/green/domain/example/dto/PostRequest.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.example.green.domain.example.dto; - -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Size; -import lombok.Data; - -@Data -@Schema(description = "게시글 생성/수정 요청 DTO") -public class PostRequest { - - @NotBlank(message = "제목은 필수입니다.") - @Size(min = 5, max = 100, message = "제목은 5자 이상 20자 이하로 입력해주세요.") - @Schema(description = "게시글 제목", example = "오늘의 공부 일지") - private String title; - - @NotBlank(message = "내용은 필수입니다.") - @Size(min = 10, max = 1000, message = "내용은 10자 이상 1000자 이하로 입력해주세요.") - @Schema(description = "게시글 내용", example = "오늘은 Swagger 문서화에 대해 배웠다.") - private String content; - - @Min(value = 1, message = "챌린지 ID는 1이상의 숫자여야 합니다.") - @Schema(description = "챌린지 ID", example = "2") - private Long challengeId; -} diff --git a/src/main/java/com/example/green/domain/example/dto/PostResponse.java b/src/main/java/com/example/green/domain/example/dto/PostResponse.java deleted file mode 100644 index 9efe39ad..00000000 --- a/src/main/java/com/example/green/domain/example/dto/PostResponse.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.example.green.domain.example.dto; - -import java.time.LocalDateTime; - -import io.swagger.v3.oas.annotations.media.Schema; -import lombok.AllArgsConstructor; -import lombok.Data; - -@Data -@AllArgsConstructor -@Schema(description = "게시글 응답 DTO") -public class PostResponse { - - @Schema(description = "게시글 ID", example = "1") - private Long id; - - @Schema(description = "게시글 제목", example = "오늘의 공부 일지") - private String title; - - @Schema(description = "게시글 내용", example = "오늘은 Swagger 문서화에 대해 배웠다.") - private String content; - - @Schema(description = "작성자", example = "홍길동") - private String author; - - @Schema(description = "작성일시", example = "2024-05-18T12:30:00") - private LocalDateTime createdAt; -} diff --git a/src/main/java/com/example/green/domain/example/tools/DbInitializer.java b/src/main/java/com/example/green/domain/example/tools/DbInitializer.java deleted file mode 100644 index 1e1c7881..00000000 --- a/src/main/java/com/example/green/domain/example/tools/DbInitializer.java +++ /dev/null @@ -1,220 +0,0 @@ -package com.example.green.domain.example.tools; - -import static com.example.green.domain.pointshop.product.entity.vo.DisplayStatus.*; -import static com.example.green.domain.pointshop.product.entity.vo.SellingStatus.*; - -import java.lang.reflect.Field; -import java.math.BigDecimal; -import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; -import java.util.UUID; - -import org.springframework.context.annotation.Profile; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.util.ReflectionUtils; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -import com.example.green.domain.common.BaseEntity; -import com.example.green.domain.member.entity.Member; -import com.example.green.domain.member.repository.MemberRepository; -import com.example.green.domain.point.entity.PointTransaction; -import com.example.green.domain.point.entity.vo.PointAmount; -import com.example.green.domain.point.entity.vo.PointSource; -import com.example.green.domain.point.entity.vo.TargetType; -import com.example.green.domain.point.repository.PointTransactionRepository; -import com.example.green.domain.pointshop.delivery.entity.DeliveryAddress; -import com.example.green.domain.pointshop.delivery.entity.vo.Address; -import com.example.green.domain.pointshop.delivery.entity.vo.Recipient; -import com.example.green.domain.pointshop.delivery.repository.DeliveryAddressRepository; -import com.example.green.domain.pointshop.order.entity.Order; -import com.example.green.domain.pointshop.order.entity.OrderItem; -import com.example.green.domain.pointshop.order.entity.vo.DeliveryAddressSnapshot; -import com.example.green.domain.pointshop.order.entity.vo.ItemSnapshot; -import com.example.green.domain.pointshop.order.entity.vo.MemberSnapshot; -import com.example.green.domain.pointshop.order.repository.OrderRepository; -import com.example.green.domain.pointshop.product.entity.PointProduct; -import com.example.green.domain.pointshop.product.entity.vo.BasicInfo; -import com.example.green.domain.pointshop.product.entity.vo.Code; -import com.example.green.domain.pointshop.product.entity.vo.Media; -import com.example.green.domain.pointshop.product.entity.vo.Price; -import com.example.green.domain.pointshop.product.entity.vo.Stock; -import com.example.green.domain.pointshop.product.repository.PointProductRepository; - -import io.swagger.v3.oas.annotations.Hidden; -import lombok.RequiredArgsConstructor; - -@Profile("!prod") -@RestController -@RequiredArgsConstructor -@Transactional -@Hidden -public class DbInitializer { - - private static final Random random = new Random(); - private static final LocalDateTime baseTime = LocalDateTime.now(); - private static final Map lastIds = new HashMap<>(); - private final PointProductRepository pointProductRepository; - private final PointTransactionRepository pointTransactionRepository; - - @GetMapping("/api/tools/init-db-point-products") - public void initialize() { - pointProductRepository.deleteAll(); - List pointProducts = new ArrayList<>(); - int batchSize = 100; - for (int i = 0; i < 1000; i++) { - char ch1 = (char)('A' + random.nextInt(26)); - char ch2 = (char)('A' + random.nextInt(26)); - String prefix = String.format("%c%c", ch1, ch2); - int number = lastIds.getOrDefault(prefix, 0); - String code = String.format("PRD-%s-%03d", prefix, number); - lastIds.put(prefix, number + 1); - String name = String.format("랜덤 상품 %d", i + 1); - PointProduct product = createRandomProduct(code, name, i); - pointProducts.add(product); - if (pointProducts.size() >= batchSize) { - List savedProducts = pointProductRepository.saveAll(pointProducts); - - for (int j = 0; j < savedProducts.size(); j++) { - PointProduct saved = savedProducts.get(j); - int dayOffset = i - batchSize + j + 1; - LocalDateTime randomDate = baseTime.minusDays(dayOffset); - Field field = ReflectionUtils.findField(BaseEntity.class, "createdDate"); - if (field != null) { - ReflectionUtils.makeAccessible(field); - ReflectionUtils.setField(field, saved, randomDate); - } - } - - pointProductRepository.saveAll(savedProducts); - pointProducts.clear(); - } - } - } - - static String[] targets = { - "달리기 챌린지", "눈물 나는 챌린지", "기쁜 챌린지", "짜증나는 챌린지", "웃긴 상품", "가짜 상품", "꽝 상품", "랜덤 상품", "1억 상품" - }; - - @GetMapping("/api/tools/init-db-point-transaction") - public void initPointTransaction() { - List pointTransactions = new ArrayList<>(); - PointAmount currentBalance = PointAmount.of(BigDecimal.ZERO); - - for (int i = 0; i < 100; i++) { - String target = targets[random.nextInt(targets.length)]; - boolean isChallenge = target.contains("챌린지"); - - PointSource pointSource; - PointAmount amount; - PointTransaction transaction; - LocalDateTime transactionAt = baseTime.minusDays(i); - - if (isChallenge) { - String detail = target + " 적립"; - pointSource = PointSource.ofTarget(random.nextLong(1, 100), detail, TargetType.CHALLENGE); - int amountPrice = 1000 + random.nextInt(4000); - amount = PointAmount.of(BigDecimal.valueOf(amountPrice)); - - PointAmount previousBalance = currentBalance; - currentBalance = currentBalance.add(amount); - transaction = PointTransaction.earn(1L, pointSource, amount, previousBalance, transactionAt); - } else { - String detail = target + " 교환"; - pointSource = PointSource.ofTarget(random.nextLong(1, 100), detail, TargetType.EXCHANGE); - - int amountPrice = 1000 + random.nextInt(4000); - amount = PointAmount.of(BigDecimal.valueOf(amountPrice)); - - if (currentBalance.canSpend(amount)) { - PointAmount previousBalance = currentBalance; - currentBalance = currentBalance.subtract(amount); - transaction = PointTransaction.spend(1L, pointSource, amount, previousBalance, transactionAt); - } else { - String earnDetail = "보너스 적립"; - PointSource earnSource = PointSource.ofEvent(earnDetail); - PointAmount earnAmount = PointAmount.of(BigDecimal.valueOf(10000)); - - PointAmount previousBalance = currentBalance; - currentBalance = currentBalance.add(earnAmount); - transaction = PointTransaction.earn(1L, earnSource, earnAmount, previousBalance, transactionAt); - } - } - pointTransactions.add(transaction); - } - pointTransactionRepository.saveAll(pointTransactions); - } - - private static PointProduct createRandomProduct(String code, String name, int day) { - return PointProduct.builder() - .code(new Code(code)) - .basicInfo(new BasicInfo(name, name + " 상품")) - .media(new Media("https://example.com/images/" + code.toLowerCase() + ".jpg")) - .price(new Price(BigDecimal.valueOf((random.nextInt(100) + 1) * 1000))) - .stock(new Stock(random.nextInt(51))) - .sellingStatus(random.nextInt(10) < 8 ? EXCHANGEABLE : SOLD_OUT) - .displayStatus(random.nextInt(10) < 8 ? DISPLAY : HIDDEN) - .build(); - } - - static String[] firstName = {"김", "이", "박", "최", "강", "구", "오", "정"}; - static String[] secondName = {"길동", "순신", "황", "종서", "호동", "재석", "명수", "재훈", "랜덤"}; - private final DeliveryAddressRepository deliveryAddressRepository; - - @GetMapping("/api/tools/init-db-deliveryAddresses") - public void initDeliveryAddresses() { - List deliveryAddresses = new ArrayList<>(); - for (int i = 0; i < 100; i++) { - String name = firstName[random.nextInt(firstName.length)] - + " " - + secondName[random.nextInt(secondName.length)]; - String phoneNumber = "010-" + random.nextInt(1000, 10000) + "-" + random.nextInt(1000, 10000); - Recipient recipient = Recipient.of(name, phoneNumber); - Address address = Address.of("랜덤 도로명" + i, "상세 주소" + i, String.valueOf(random.nextInt(10000, 100000))); - DeliveryAddress deliveryAddress = DeliveryAddress.create(i + 1L, recipient, address); - deliveryAddresses.add(deliveryAddress); - } - deliveryAddressRepository.saveAll(deliveryAddresses); - } - - private final OrderRepository orderRepository; - - @GetMapping("/api/tools/init-db-orders") - public void initOrders() { - List orders = new ArrayList<>(); - for (int i = 0; i < 100; i++) { - String name = firstName[random.nextInt(firstName.length)] - + " " - + secondName[random.nextInt(secondName.length)]; - String phoneNumber = "010-" + random.nextInt(1000, 10000) + "-" + random.nextInt(1000, 10000); - DeliveryAddressSnapshot deliveryAddressSnapshot = DeliveryAddressSnapshot.of( - i + 1L, name, phoneNumber, "랜덤 도로명" + i, "상세 주소" + i, - String.valueOf(random.nextInt(10000, 100000))); - MemberSnapshot memberSnapshot = new MemberSnapshot(random.nextLong(1, 101), UUID.randomUUID().toString(), - UUID.randomUUID().toString()); - int price = random.nextInt(1000, 10000); - ItemSnapshot itemSnapshot = - new ItemSnapshot(i + 1L, "랜덤 아이템" + i, UUID.randomUUID().toString(), BigDecimal.valueOf(price)); - OrderItem orderItem = OrderItem.create(itemSnapshot, random.nextInt(1, 6)); - Order order = Order.create(deliveryAddressSnapshot, memberSnapshot, List.of(orderItem)); - orders.add(order); - } - orderRepository.saveAll(orders); - } - - private final MemberRepository memberRepository; - - @GetMapping("/api/tools/init-db-members") - public void createMembers() { - List members = new ArrayList<>(); - for (int i = 0; i < 100; i++) { - Member member = Member.create("name" + i, "nickname" + i, "email" + i); - members.add(member); - } - memberRepository.saveAll(members); - } -} diff --git a/src/main/java/com/example/green/domain/example/tools/FakeAuthTools.java b/src/main/java/com/example/green/domain/example/tools/FakeAuthTools.java deleted file mode 100644 index 9e0ebce9..00000000 --- a/src/main/java/com/example/green/domain/example/tools/FakeAuthTools.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.example.green.domain.example.tools; - -import static com.example.green.domain.auth.constants.AuthConstants.*; - -import java.util.Optional; - -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RestController; - -import com.example.green.domain.auth.admin.entity.Admin; -import com.example.green.domain.auth.dto.TokenResponseDto; -import com.example.green.domain.auth.entity.vo.AccessToken; -import com.example.green.domain.auth.service.TokenService; -import com.example.green.domain.auth.utils.WebUtils; -import com.example.green.domain.member.entity.Member; -import com.example.green.domain.member.repository.MemberRepository; - -import io.swagger.v3.oas.annotations.Hidden; -import org.springframework.http.ResponseCookie; -import jakarta.servlet.http.HttpServletRequest; -import jakarta.servlet.http.HttpServletResponse; -import lombok.RequiredArgsConstructor; - -@RestController -@RequiredArgsConstructor -@Hidden -public class FakeAuthTools { - - private static final int REFRESH_TOKEN_MAX_AGE = 7 * 24 * 60 * 60; // 7일 - - private final MemberRepository memberRepository; - private final TokenService tokenService; - - @GetMapping("/auth/{id}") - public ResponseEntity fakeAuth(@PathVariable Long id, - HttpServletRequest httpRequest, - HttpServletResponse response) { - Optional byId = memberRepository.findById(id); - Member member = byId.get(); - String memberKey = member.getMemberKey(); - String accessTokenString = tokenService.createAccessToken(memberKey, ROLE_USER); - AccessToken accessToken = AccessToken.from(accessTokenString, tokenService); - String refreshTokenString = tokenService.createRefreshToken( - memberKey, - WebUtils.extractDeviceInfo(httpRequest), - WebUtils.extractClientIp(httpRequest) - ); - ResponseCookie cookie = WebUtils.createRefreshTokenCookie( - refreshTokenString, - WebUtils.isSecureRequest(httpRequest), - REFRESH_TOKEN_MAX_AGE - ); - response.addHeader("Set-Cookie", cookie.toString()); - - return ResponseEntity.ok(new TokenResponseDto( - accessToken.getValue(), - member.getMemberKey(), - member.getName() - )); - } - - @GetMapping("/auth/admin") - public ResponseEntity fakeAuth() { - Optional byId = memberRepository.findById(1L); - Member member = byId.get(); - String accessTokenString = tokenService.createAccessToken(member.getMemberKey(), Admin.ROLE_ADMIN); - AccessToken accessToken = AccessToken.from(accessTokenString, tokenService); - - return ResponseEntity.ok(new TokenResponseDto( - accessToken.getValue(), - member.getMemberKey(), - member.getName() - )); - } -}