diff --git a/src/main/java/org/fontory/fontorybe/common/controller/GlobalExceptionHandler.java b/src/main/java/org/fontory/fontorybe/common/controller/GlobalExceptionHandler.java index 0ae8efb..3ece7b7 100644 --- a/src/main/java/org/fontory/fontorybe/common/controller/GlobalExceptionHandler.java +++ b/src/main/java/org/fontory/fontorybe/common/controller/GlobalExceptionHandler.java @@ -10,6 +10,7 @@ import org.fontory.fontorybe.file.adapter.inbound.exception.FileUploadException; import org.fontory.fontorybe.file.domain.exception.InvalidMultipartRequestException; import org.fontory.fontorybe.file.domain.exception.SingleFileRequiredException; +import org.fontory.fontorybe.font.domain.exception.FontDuplicateNameExistsException; import org.fontory.fontorybe.font.domain.exception.FontNotFoundException; import org.fontory.fontorybe.font.domain.exception.FontOwnerMismatchException; import org.fontory.fontorybe.font.domain.exception.FontSQSProduceExcepetion; @@ -34,8 +35,8 @@ public BaseErrorResponse notFoundException(Exception e) { } @ResponseStatus(HttpStatus.FORBIDDEN) - @ExceptionHandler(MemberDuplicateNameExistsException.class) - public BaseErrorResponse memberDuplicateNameExists(MemberDuplicateNameExistsException e) { + @ExceptionHandler({MemberDuplicateNameExistsException.class, FontDuplicateNameExistsException.class}) + public BaseErrorResponse duplicateNameExists(Exception e) { return new BaseErrorResponse(e.getMessage()); } diff --git a/src/main/java/org/fontory/fontorybe/font/controller/FontController.java b/src/main/java/org/fontory/fontorybe/font/controller/FontController.java index ea474b3..ac96e2d 100644 --- a/src/main/java/org/fontory/fontorybe/font/controller/FontController.java +++ b/src/main/java/org/fontory/fontorybe/font/controller/FontController.java @@ -307,4 +307,24 @@ public ResponseEntity downloadFont( .status(HttpStatus.OK) .body(res); } + + @Operation( + summary = "폰트 이름 중복 검사", + description = "이름이 중복이면 true를 반환합니다." + ) + @PostMapping("/verify-name") + public ResponseEntity verifyFontName( + @Login UserPrincipal userPrincipal, + @RequestBody FontCreateDTO fontCreateDTO + ) { + Long memberId = userPrincipal.getId(); + log.info("Request received: Check if font name is duplicate: {}", fontCreateDTO.getName()); + + Boolean duplicateNameExist = fontService.isDuplicateNameExists(memberId, fontCreateDTO.getName()); + log.info("Response sent: Font name {} is {}", fontCreateDTO.getName(), duplicateNameExist ? "duplicate" : "available"); + + return ResponseEntity + .status(HttpStatus.OK) + .body(duplicateNameExist); + } } diff --git a/src/main/java/org/fontory/fontorybe/font/controller/port/FontService.java b/src/main/java/org/fontory/fontorybe/font/controller/port/FontService.java index 6117354..8f4b146 100644 --- a/src/main/java/org/fontory/fontorybe/font/controller/port/FontService.java +++ b/src/main/java/org/fontory/fontorybe/font/controller/port/FontService.java @@ -26,4 +26,5 @@ public interface FontService { List getPopularFonts(Long memberId); Font updateProgress(Long fontId, FontProgressUpdateDTO fontProgressUpdateDTO); FontResponse fontDownload(Long memberId, Long fontId); + Boolean isDuplicateNameExists(Long memberId, String fontName); } diff --git a/src/main/java/org/fontory/fontorybe/font/domain/exception/FontDuplicateNameExistsException.java b/src/main/java/org/fontory/fontorybe/font/domain/exception/FontDuplicateNameExistsException.java new file mode 100644 index 0000000..b322ab2 --- /dev/null +++ b/src/main/java/org/fontory/fontorybe/font/domain/exception/FontDuplicateNameExistsException.java @@ -0,0 +1,10 @@ +package org.fontory.fontorybe.font.domain.exception; + +import org.fontory.fontorybe.common.domain.SkipDiscordNotification; + +@SkipDiscordNotification +public class FontDuplicateNameExistsException extends RuntimeException { + public FontDuplicateNameExistsException() { + super("Font name is duplicate"); + } +} diff --git a/src/main/java/org/fontory/fontorybe/font/infrastructure/FontJpaRepository.java b/src/main/java/org/fontory/fontorybe/font/infrastructure/FontJpaRepository.java index 5f4cdb9..e44409a 100644 --- a/src/main/java/org/fontory/fontorybe/font/infrastructure/FontJpaRepository.java +++ b/src/main/java/org/fontory/fontorybe/font/infrastructure/FontJpaRepository.java @@ -19,4 +19,5 @@ public interface FontJpaRepository extends JpaRepository { List findTop4ByMemberIdOrderByDownloadAndBookmarkCountDesc(@Param("memberId") Long memberId, Pageable pageable); @Query("SELECT f FROM FontEntity f ORDER BY (f.downloadCount + f.bookmarkCount) DESC") List findTop3OrderByDownloadAndBookmarkCountDesc(Pageable pageable); + boolean existsByName(String fontName); } diff --git a/src/main/java/org/fontory/fontorybe/font/infrastructure/FontRepositoryImpl.java b/src/main/java/org/fontory/fontorybe/font/infrastructure/FontRepositoryImpl.java index dc90954..ae59511 100644 --- a/src/main/java/org/fontory/fontorybe/font/infrastructure/FontRepositoryImpl.java +++ b/src/main/java/org/fontory/fontorybe/font/infrastructure/FontRepositoryImpl.java @@ -106,4 +106,9 @@ public List findTop3OrderByDownloadAndBookmarkCountDesc() { .map(FontEntity::toModel) .collect(Collectors.toList()); } + + @Override + public boolean existsByName(String fontName) { + return fontJpaRepository.existsByName(fontName); + } } diff --git a/src/main/java/org/fontory/fontorybe/font/service/FontServiceImpl.java b/src/main/java/org/fontory/fontorybe/font/service/FontServiceImpl.java index a32aa69..11d682f 100644 --- a/src/main/java/org/fontory/fontorybe/font/service/FontServiceImpl.java +++ b/src/main/java/org/fontory/fontorybe/font/service/FontServiceImpl.java @@ -15,6 +15,7 @@ import org.fontory.fontorybe.font.controller.dto.FontUpdateDTO; import org.fontory.fontorybe.font.controller.port.FontService; import org.fontory.fontorybe.font.domain.Font; +import org.fontory.fontorybe.font.domain.exception.FontDuplicateNameExistsException; import org.fontory.fontorybe.font.domain.exception.FontNotFoundException; import org.fontory.fontorybe.font.domain.exception.FontOwnerMismatchException; import org.fontory.fontorybe.font.service.dto.FontRequestProduceDto; @@ -46,6 +47,10 @@ public Font create(Long memberId, FontCreateDTO fontCreateDTO, FileDetails fileD log.info("Service executing: Creating font for member ID: {}, font name: {}", memberId, fontCreateDTO.getName()); Member member = memberService.getOrThrowById(memberId); + if (isDuplicateNameExists(memberId, fontCreateDTO.getName())) { + throw new FontDuplicateNameExistsException(); + } + Font savedFont = fontRepository.save(Font.from(fontCreateDTO, member.getId(), fileDetails)); fontRequestProducer.sendFontRequest(FontRequestProduceDto.from(savedFont, member)); @@ -297,6 +302,13 @@ public FontResponse fontDownload(Long memberId, Long fontId) { return FontResponse.from(targetFont, isBookmarked, writer.getNickname()); } + @Override + @Transactional(readOnly = true) + public Boolean isDuplicateNameExists(Long memberId, String fontName) { + Member member = memberService.getOrThrowById(memberId); + return fontRepository.existsByName(fontName); + } + private void checkFontOwnership(Long requestMemberId, Long targetMemberId) { log.debug("Service detail: Checking font ownership: requestMemberId={}, targetMemberId={}", requestMemberId, targetMemberId); diff --git a/src/main/java/org/fontory/fontorybe/font/service/port/FontRepository.java b/src/main/java/org/fontory/fontorybe/font/service/port/FontRepository.java index fce7da7..bf6fc7b 100644 --- a/src/main/java/org/fontory/fontorybe/font/service/port/FontRepository.java +++ b/src/main/java/org/fontory/fontorybe/font/service/port/FontRepository.java @@ -18,4 +18,5 @@ public interface FontRepository { List findAllByIdIn(List ids); List findTop4ByMemberIdOrderByDownloadAndBookmarkCountDesc(Long memberId); List findTop3OrderByDownloadAndBookmarkCountDesc(); + boolean existsByName(String fontName); }