diff --git a/backend/src/main/java/codezap/category/domain/Category.java b/backend/src/main/java/codezap/category/domain/Category.java index 818b99453..a1621b296 100644 --- a/backend/src/main/java/codezap/category/domain/Category.java +++ b/backend/src/main/java/codezap/category/domain/Category.java @@ -22,10 +22,10 @@ @AllArgsConstructor @Getter @Table( - uniqueConstraints={ + uniqueConstraints = { @UniqueConstraint( - name="name_with_member", - columnNames={"member_id", "name"} + name = "name_with_member", + columnNames = {"member_id", "name"} ) } ) diff --git a/backend/src/main/java/codezap/global/swagger/error/ApiErrorResponsesCustomizer.java b/backend/src/main/java/codezap/global/swagger/error/ApiErrorResponsesCustomizer.java index 05bf8b5e7..f61ac0463 100644 --- a/backend/src/main/java/codezap/global/swagger/error/ApiErrorResponsesCustomizer.java +++ b/backend/src/main/java/codezap/global/swagger/error/ApiErrorResponsesCustomizer.java @@ -21,7 +21,8 @@ public class ApiErrorResponsesCustomizer implements OperationCustomizer { @Override public Operation customize(Operation operation, HandlerMethod handlerMethod) { if (handlerMethod.hasMethodAnnotation(ApiErrorResponse.class)) { - ApiErrorResponse apiErrorResponse = Objects.requireNonNull(handlerMethod.getMethodAnnotation(ApiErrorResponse.class)); + ApiErrorResponse apiErrorResponse = Objects.requireNonNull( + handlerMethod.getMethodAnnotation(ApiErrorResponse.class)); ApiResponses responses = operation.getResponses(); String statusCode = String.valueOf(apiErrorResponse.status().value()); responses.addApiResponse(statusCode, makeFailResponse(apiErrorResponse)); diff --git a/backend/src/main/java/codezap/member/controller/SpringDocMemberController.java b/backend/src/main/java/codezap/member/controller/SpringDocMemberController.java index 8d5f4a06a..431db21ca 100644 --- a/backend/src/main/java/codezap/member/controller/SpringDocMemberController.java +++ b/backend/src/main/java/codezap/member/controller/SpringDocMemberController.java @@ -195,7 +195,9 @@ public interface SpringDocMemberController { @ApiResponse( responseCode = "200", description = "로그인 성공", - headers = {@Header(name = "Set-Cookie", description = "base64(${email}:${password}); path=\"/\"; HttpOnly; Secure;")} + headers = { + @Header(name = "Set-Cookie", description = "base64(${email}:${password}); path=\"/\"; HttpOnly; " + + "Secure;")} ) @ApiResponse( responseCode = "400", diff --git a/backend/src/main/java/codezap/member/service/MemberService.java b/backend/src/main/java/codezap/member/service/MemberService.java index e9dcf2dbd..4eb271f77 100644 --- a/backend/src/main/java/codezap/member/service/MemberService.java +++ b/backend/src/main/java/codezap/member/service/MemberService.java @@ -57,7 +57,7 @@ public void validateMemberId(MemberDto memberDto, Long memberId) { throw new CodeZapException(HttpStatus.UNAUTHORIZED, "다른 사람의 템플릿은 확인할 수 없습니다."); } - if(!memberRepository.existsById(memberId)) { + if (!memberRepository.existsById(memberId)) { throw new CodeZapException(HttpStatus.UNAUTHORIZED, "로그인 정보가 잘못되었습니다."); } } diff --git a/backend/src/main/java/codezap/template/controller/SpringDocTemplateController.java b/backend/src/main/java/codezap/template/controller/SpringDocTemplateController.java index 9b944bbb4..616adc60a 100644 --- a/backend/src/main/java/codezap/template/controller/SpringDocTemplateController.java +++ b/backend/src/main/java/codezap/template/controller/SpringDocTemplateController.java @@ -1,8 +1,8 @@ package codezap.template.controller; -import org.springframework.data.domain.Pageable; import java.util.List; +import org.springframework.data.domain.Pageable; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -11,7 +11,6 @@ import codezap.member.dto.MemberDto; import codezap.template.dto.request.CreateTemplateRequest; import codezap.template.dto.request.UpdateTemplateRequest; -import codezap.template.dto.response.FindAllMyTemplatesResponse; import codezap.template.dto.response.ExploreTemplatesResponse; import codezap.template.dto.response.FindAllTemplatesResponse; import codezap.template.dto.response.FindTemplateResponse; @@ -44,20 +43,28 @@ public interface SpringDocTemplateController { }) ResponseEntity create(CreateTemplateRequest createTemplateRequest, MemberDto memberDto); - @Operation(summary = "템플릿 목록 조회", description = """ - 조건에 맞는 모든 템플릿을 조회합니다. - 필터링 조건은 작성자 Id, 카테고리 Id, 태그 목록을 사용할 수 있습니다. + @Operation(summary = "템플릿 검색", description = """ + 필터링 조건에 맞는 모든 템플릿을 조회합니다. + - 필터링 조건 + - 멤버 ID + - 검색 키워드 (템플릿 제목, 템플릿 설명, 스니펫 파일명, 소스 코드) + - 카테고리 ID + - 태그 ID + - 정렬 방식 + - 최신순 (createdAt,asc) + - 오래된순 (createdAt,desc) 조회 조건으로 페이지 인덱스, 한 페이지에 들어갈 최대 템플릿의 개수를 변경할 수 있습니다. 페이지 인덱스는 1, 템플릿 개수는 20개가 기본 값입니다. """) @ApiResponse(responseCode = "200", description = "템플릿 단건 조회 성공", content = {@Content(schema = @Schema(implementation = ExploreTemplatesResponse.class))}) ResponseEntity getTemplates( - //Long memberId, - Integer pageNumber, - Integer pageSize, + MemberDto memberDto, + Long memberId, + String keyword, Long categoryId, - List tagNames + List tagIds, + Pageable pageable ); @Operation(summary = "템플릿 단건 조회", description = "해당하는 식별자의 템플릿을 조회합니다.") @@ -69,13 +76,6 @@ ResponseEntity getTemplates( }) ResponseEntity getTemplateById(Long id, MemberDto memberDto); - @Operation(summary = "템플릿 토픽 검색", description = "토픽이 포함된 템플릿들을 검색합니다.") - @ApiResponse(responseCode = "200", description = "템플릿 토픽 검색 성공", - content = {@Content(schema = @Schema(implementation = FindAllTemplatesResponse.class))}) - ResponseEntity getMyTemplatesContainTopic( - MemberDto memberDto, Long memberId, String topic, Pageable pageable - ); - @Operation(summary = "템플릿 수정", description = "해당하는 식별자의 템플릿을 수정합니다.") @ApiResponse(responseCode = "200", description = "템플릿 수정 성공") @ApiErrorResponse(status = HttpStatus.BAD_REQUEST, instance = "/templates/1", errorCases = { diff --git a/backend/src/main/java/codezap/template/controller/TemplateController.java b/backend/src/main/java/codezap/template/controller/TemplateController.java index 08c94201a..216abf45f 100644 --- a/backend/src/main/java/codezap/template/controller/TemplateController.java +++ b/backend/src/main/java/codezap/template/controller/TemplateController.java @@ -5,9 +5,6 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.web.PageableDefault; -import org.apache.commons.lang3.NotImplementedException; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.repository.query.Param; import org.springframework.http.ResponseEntity; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.DeleteMapping; @@ -24,11 +21,9 @@ import codezap.member.dto.MemberDto; import codezap.template.dto.request.CreateTemplateRequest; import codezap.template.dto.request.UpdateTemplateRequest; -import codezap.template.dto.response.FindAllMyTemplatesResponse; import codezap.template.dto.response.ExploreTemplatesResponse; import codezap.template.dto.response.FindAllTemplatesResponse; import codezap.template.dto.response.FindTemplateResponse; -import codezap.template.service.MyTemplateFacadeService; import codezap.template.service.TemplateService; @RestController @@ -36,11 +31,9 @@ public class TemplateController implements SpringDocTemplateController { private final TemplateService templateService; - private final MyTemplateFacadeService myTemplateFacadeService; - public TemplateController(TemplateService templateService, MyTemplateFacadeService myTemplateFacadeService) { + public TemplateController(TemplateService templateService) { this.templateService = templateService; - this.myTemplateFacadeService = myTemplateFacadeService; } @PostMapping @@ -55,14 +48,16 @@ public ResponseEntity create( @GetMapping public ResponseEntity getTemplates( - //@RequestParam Long memberId, - @RequestParam(required = false, defaultValue = "1") Integer pageNumber, - @RequestParam(required = false, defaultValue = "20") Integer pageSize, + @BasicAuthentication MemberDto memberDto, + @RequestParam Long memberId, + @RequestParam String keyword, @RequestParam(required = false) Long categoryId, - @RequestParam(required = false) List tags + @RequestParam(required = false) List tagIds, + @PageableDefault(size = 20, page = 1) Pageable pageable ) { - - return ResponseEntity.ok(templateService.findAllBy(PageRequest.of(pageNumber - 1, pageSize), categoryId, tags)); + FindAllTemplatesResponse response = + templateService.findAllBy(memberId, keyword, categoryId, tagIds, pageable); + return ResponseEntity.ok(response); } @GetMapping("/explore") @@ -71,20 +66,10 @@ public ResponseEntity explore() { } @GetMapping("/{id}") - public ResponseEntity getTemplateById(@PathVariable Long id, @BasicAuthentication MemberDto memberDto) { - return ResponseEntity.ok(templateService.findByIdAndMember(id, memberDto)); - } - - @GetMapping("/search") - public ResponseEntity getMyTemplatesContainTopic( - @BasicAuthentication MemberDto memberDto, - @RequestParam("memberId") Long memberId, - @RequestParam("topic") String topic, - @PageableDefault Pageable pageable + public ResponseEntity getTemplateById(@PathVariable Long id, + @BasicAuthentication MemberDto memberDto ) { - FindAllMyTemplatesResponse response = myTemplateFacadeService - .searchMyTemplatesContainTopic(memberDto, memberId, topic, pageable); - return ResponseEntity.ok(response); + return ResponseEntity.ok(templateService.findByIdAndMember(id, memberDto)); } @PostMapping("/{id}") diff --git a/backend/src/main/java/codezap/template/domain/Template.java b/backend/src/main/java/codezap/template/domain/Template.java index 4e7a9c436..e3faf2060 100644 --- a/backend/src/main/java/codezap/template/domain/Template.java +++ b/backend/src/main/java/codezap/template/domain/Template.java @@ -6,7 +6,6 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; -import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import codezap.category.domain.Category; diff --git a/backend/src/main/java/codezap/template/dto/response/FindAllMyTemplatesResponse.java b/backend/src/main/java/codezap/template/dto/response/FindAllMyTemplatesResponse.java deleted file mode 100644 index 0efa46369..000000000 --- a/backend/src/main/java/codezap/template/dto/response/FindAllMyTemplatesResponse.java +++ /dev/null @@ -1,20 +0,0 @@ -package codezap.template.dto.response; - -import java.util.List; - -import io.swagger.v3.oas.annotations.media.Schema; - -public record FindAllMyTemplatesResponse( - @Schema(description = "총 페이지", example = "5") - long totalPage, - - @Schema(description = "템플릿 목록") - List templates -) { - public static FindAllMyTemplatesResponse of(List myTemplateResponses, long totalPage) { - return new FindAllMyTemplatesResponse( - totalPage, - myTemplateResponses - ); - } -} diff --git a/backend/src/main/java/codezap/template/dto/response/FindMyTemplateResponse.java b/backend/src/main/java/codezap/template/dto/response/FindMyTemplateResponse.java deleted file mode 100644 index 01607c123..000000000 --- a/backend/src/main/java/codezap/template/dto/response/FindMyTemplateResponse.java +++ /dev/null @@ -1,44 +0,0 @@ -package codezap.template.dto.response; - -import java.time.LocalDateTime; -import java.util.List; - -import codezap.template.domain.Tag; -import codezap.template.domain.Template; -import io.swagger.v3.oas.annotations.media.Schema; - -public record FindMyTemplateResponse( - @Schema(description = "템플릿 식별자", example = "0") - Long id, - - @Schema(description = "템플릿 이름", example = "스프링 로그인 구현") - String title, - - @Schema(description = "템플릿 설명", example = "JWT를 사용하여 로그인 기능을 구현함") - String description, - - @Schema(description = "태그 목록") - List tags, - - @Schema(description = "템플릿 수정 시간", example = "2024-11-11 12:00", type = "string") - LocalDateTime modifiedAt -) { - public static FindMyTemplateResponse of(Template template, List tags) { - return new FindMyTemplateResponse( - template.getId(), - template.getTitle(), - template.getDescription(), - mapToFindTagByTemplateResponse(tags), - template.getModifiedAt() - ); - } - - private static List mapToFindTagByTemplateResponse( - List tags - ) { - return tags.stream() - .map(FindTagResponse::from) - .toList(); - } -} - diff --git a/backend/src/main/java/codezap/template/repository/TagRepository.java b/backend/src/main/java/codezap/template/repository/TagRepository.java index 8ff7f3b85..0a31fe0cd 100644 --- a/backend/src/main/java/codezap/template/repository/TagRepository.java +++ b/backend/src/main/java/codezap/template/repository/TagRepository.java @@ -20,5 +20,5 @@ default Tag fetchById(Long id) { Optional findByName(String name); - List findByNameIn(List tagNames); + List findByIdIn(List tagIds); } diff --git a/backend/src/main/java/codezap/template/repository/TemplateRepository.java b/backend/src/main/java/codezap/template/repository/TemplateRepository.java index 34ddb0f69..7c504960d 100644 --- a/backend/src/main/java/codezap/template/repository/TemplateRepository.java +++ b/backend/src/main/java/codezap/template/repository/TemplateRepository.java @@ -3,7 +3,6 @@ import java.util.List; import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -27,26 +26,75 @@ default Template fetchById(Long id) { FROM Template t JOIN Snippet s ON t.id = s.template.id WHERE t.member.id = :memberId AND ( - t.title LIKE :topic - OR s.filename LIKE :topic - OR s.content LIKE :topic - OR t.description LIKE :topic + t.title LIKE :keyword + OR s.filename LIKE :keyword + OR s.content LIKE :keyword + OR t.description LIKE :keyword ) """) - Page