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
22 changes: 21 additions & 1 deletion src/docs/asciidoc/user-api.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -266,4 +266,24 @@ include::{snippetsDir}/loadMyBookmarkPosts/3/http-response.adoc[]

실패 3. 요청 페이지당 개수 유효성 검증에 실패할 경우

include::{snippetsDir}/loadMyBookmarkPosts/4/http-response.adoc[]
include::{snippetsDir}/loadMyBookmarkPosts/4/http-response.adoc[]

=== **13. 북마크 삭제 api**

사용자가 등록한 북마크를 삭제합니다.

==== Request
include::{snippetsDir}/deleteBookmark/1/http-request.adoc[]

==== Request Body Fields
include::{snippetsDir}/deleteBookmark/1/request-fields.adoc[]

==== 성공 Response
include::{snippetsDir}/deleteBookmark/1/http-response.adoc[]

==== 실패 Response
실패 1. 해당 사용자와 게시글로 구성된 북마크가 존재하지 않음.
include::{snippetsDir}/deleteBookmark/2/http-response.adoc[]

==== Response Body Fields
include::{snippetsDir}/deleteBookmark/2/response-fields.adoc[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.ftm.server.adapter.in.web.user.controller;

import com.ftm.server.adapter.in.web.user.dto.request.DeleteBookmarkRequest;
import com.ftm.server.application.command.user.DeleteBookmarkCommand;
import com.ftm.server.application.port.in.user.DeleteBookmarkUseCase;
import com.ftm.server.common.response.ApiResponse;
import com.ftm.server.infrastructure.security.UserPrincipal;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
public class DeleteBookmarkController {

private final DeleteBookmarkUseCase deleteBookmarkUseCase;

@DeleteMapping("api/users/bookmarks")
public ResponseEntity<ApiResponse> deleteBookmark(
@AuthenticationPrincipal UserPrincipal userPrincipal,
@Valid @RequestBody DeleteBookmarkRequest request) {
deleteBookmarkUseCase.execute(
DeleteBookmarkCommand.of(userPrincipal.getId(), request.getPostId()));
return ResponseEntity.status(HttpStatus.NO_CONTENT).body(null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.ftm.server.adapter.in.web.user.dto.request;

import jakarta.validation.constraints.NotNull;
import lombok.Data;

@Data
public class DeleteBookmarkRequest {
@NotNull private final Long postId;
}
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,11 @@ public void deleteBookmarkByUserList(DeleteBookmarkByUserIdCommand command) {
bookmarkRepository.deleteAllByUserIdList(command.getUserIdList());
}

@Override
public void deleteBookmarkById(DeleteBookmarkByIdCommand command) {
bookmarkRepository.deleteAllById(List.of(command.getBookmarkId()));
}

@Override
public Boolean saveBookmark(Bookmark bookmark) {
// 이미 생성된 북마크인 경우 -> false
Expand Down Expand Up @@ -287,4 +292,12 @@ public Slice<Bookmark> loadBookmarksByUserIdWithPaging(FindBookmarksByPagingQuer
.findAllByUserIdWithPaging(query)
.map(bookmarkMapper::toDomainEntity);
}

@Override
public Optional<Bookmark> loadBookmarkByUserIdAndPostId(
FindBookmarkByUserIdAndPostIdQuery query) {
Optional<BookmarkJpaEntity> bookmarkJpaEntity =
bookmarkRepository.findByUserIdAndPostId(query.getUserId(), query.getPostId());
return bookmarkJpaEntity.map(bookmarkMapper::toDomainEntity);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.ftm.server.adapter.out.persistence.model.BookmarkJpaEntity;
import java.util.List;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
Expand All @@ -24,4 +25,10 @@ public interface BookmarkRepository
int saveOrUpdate(@Param("userId") Long userId, @Param("postId") Long postId);

Boolean existsByUserIdAndPostId(Long userId, Long postId);

@Query(
value =
"select b from BookmarkJpaEntity b where b.user.id =:userId and b.post.id =:postId")
Optional<BookmarkJpaEntity> findByUserIdAndPostId(
@Param(value = "userId") Long userId, @Param(value = "postId") Long postId);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.ftm.server.application.command.user;

import lombok.Data;

@Data
public class DeleteBookmarkByIdCommand {
private final Long bookmarkId;

public static DeleteBookmarkByIdCommand of(Long bookmarkId) {
return new DeleteBookmarkByIdCommand(bookmarkId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.ftm.server.application.command.user;

import lombok.Data;

@Data
public class DeleteBookmarkCommand {
private final Long userId;
private final Long postId;

public static DeleteBookmarkCommand of(Long userId, Long postId) {
return new DeleteBookmarkCommand(userId, postId);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.ftm.server.application.port.in.user;

import com.ftm.server.application.command.user.DeleteBookmarkCommand;
import com.ftm.server.common.annotation.UseCase;

@UseCase
public interface DeleteBookmarkUseCase {
void execute(DeleteBookmarkCommand command);
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.ftm.server.application.port.out.persistence.user;

import com.ftm.server.application.command.user.DeleteBookmarkByIdCommand;
import com.ftm.server.application.command.user.DeleteBookmarkByUserIdCommand;
import com.ftm.server.common.annotation.Port;

@Port
public interface DeleteBookmarkPort {
void deleteBookmarkByUserList(DeleteBookmarkByUserIdCommand command);

void deleteBookmarkById(DeleteBookmarkByIdCommand command);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
package com.ftm.server.application.port.out.persistence.user;

import com.ftm.server.application.query.FindBookmarkByUserIdAndPostIdQuery;
import com.ftm.server.application.query.FindBookmarksByPagingQuery;
import com.ftm.server.common.annotation.Port;
import com.ftm.server.domain.entity.Bookmark;
import java.util.Optional;
import org.springframework.data.domain.Slice;

@Port
public interface LoadBookmarkPort {

Slice<Bookmark> loadBookmarksByUserIdWithPaging(FindBookmarksByPagingQuery query);

Optional<Bookmark> loadBookmarkByUserIdAndPostId(FindBookmarkByUserIdAndPostIdQuery query);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.ftm.server.application.service.user;

import com.ftm.server.application.command.user.DeleteBookmarkByIdCommand;
import com.ftm.server.application.command.user.DeleteBookmarkCommand;
import com.ftm.server.application.port.in.user.DeleteBookmarkUseCase;
import com.ftm.server.application.port.out.persistence.user.DeleteBookmarkPort;
import com.ftm.server.application.port.out.persistence.user.LoadBookmarkPort;
import com.ftm.server.application.query.FindBookmarkByUserIdAndPostIdQuery;
import com.ftm.server.common.exception.CustomException;
import com.ftm.server.common.response.enums.ErrorResponseCode;
import com.ftm.server.domain.entity.Bookmark;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class DeleteBookmarkService implements DeleteBookmarkUseCase {

private final LoadBookmarkPort loadBookmarkPort;
private final DeleteBookmarkPort deleteBookmarkPort;

@Override
@Transactional
public void execute(DeleteBookmarkCommand command) {
Bookmark bookmark =
loadBookmarkPort
.loadBookmarkByUserIdAndPostId(
FindBookmarkByUserIdAndPostIdQuery.of(
command.getUserId(), command.getPostId()))
.orElseThrow(
() -> new CustomException(ErrorResponseCode.BOOKMARK_NOT_FOUND));

deleteBookmarkPort.deleteBookmarkById(DeleteBookmarkByIdCommand.of(bookmark.getId()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public enum ErrorResponseCode {
POST_NOT_FOUND(HttpStatus.NOT_FOUND, "E404_005", "요청한 게시글을 찾을 수 없습니다."),
POST_PRODUCT_NOT_FOUND(HttpStatus.NOT_FOUND, "E404_006", "요청한 상품을 찾을 수 없습니다."),
POST_PRODUCT_IMAGE_NOT_FOUND(HttpStatus.NOT_FOUND, "E404_007", "요청한 상품 이미지를 찾을 수 없습니다."),
BOOKMARK_NOT_FOUND(HttpStatus.NOT_FOUND, "E404_008", "요청된 사용자와 게시글에 부합하는 북마크를 찾을 수 없습니다."),

// 409번
USER_ALREADY_EXISTS(HttpStatus.CONFLICT, "E409_001", "이미 존재하는 사용자입니다."),
Expand Down
Loading
Loading