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
@@ -0,0 +1,24 @@
package leets.bookmark.domain.bookmark.application.dto.response;

import leets.bookmark.domain.file.application.dto.response.FileResponse;
import leets.bookmark.domain.notification.application.dto.response.NotificationResponse;
import lombok.Builder;

import java.time.LocalDateTime;
import java.util.List;

@Builder
public record BookmarkFullResponse(
Long id,
String url,
String title,
String memo,
String platform,
String faviconUrl,
List<BookmarkTagInfoResponse> categoryTagInfos,
FileResponse file,
NotificationResponse notificationResponse,
LocalDateTime createdAt,
LocalDateTime updatedAt
) {
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package leets.bookmark.domain.bookmark.application.mapper;

import leets.bookmark.domain.bookmark.application.dto.request.BookmarkSaveRequest;
import leets.bookmark.domain.bookmark.application.dto.response.BookmarkFullResponse;
import leets.bookmark.domain.bookmark.application.dto.response.BookmarkResponse;
import leets.bookmark.domain.bookmark.domain.entity.Bookmark;
import leets.bookmark.domain.bookmark.application.dto.response.BookmarkTagInfoResponse;
import leets.bookmark.domain.bookmark.domain.entity.BookmarkTagMapping;
import leets.bookmark.domain.file.application.dto.response.FileResponse;
import leets.bookmark.domain.file.domain.entity.File;
import leets.bookmark.domain.notification.application.dto.response.NotificationResponse;
import leets.bookmark.domain.tag.domain.entity.Tag;
import leets.bookmark.domain.category.domain.entity.Category;

Expand Down Expand Up @@ -111,4 +112,24 @@ public List<BookmarkTagMapping> toMappings(Bookmark bookmark, List<Tag> tags) {
.map(tag -> toMapping(bookmark, tag))
.toList();
}

public BookmarkFullResponse toFullResponse(Bookmark bookmark, List<BookmarkTagMapping> bookmarkTagMappings,
FileResponse fileResponse, NotificationResponse notificationResponse) {

BookmarkTagInfoResponse tagInfo = toBookmarkTagInfoResponseFromMappings(bookmarkTagMappings);

return BookmarkFullResponse.builder()
.id(bookmark.getId())
.url(bookmark.getUrl())
.title(bookmark.getTitle())
.memo(bookmark.getMemo())
.platform(String.valueOf(bookmark.getPlatform()))
.faviconUrl(bookmark.getFaviconUrl())
.categoryTagInfos(List.of(tagInfo))
.file(fileResponse)
.notificationResponse(notificationResponse)
.createdAt(bookmark.getCreatedAt())
.updatedAt(bookmark.getUpdatedAt())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import leets.bookmark.domain.bookmark.application.dto.request.BookmarkSaveRequest;
import leets.bookmark.domain.bookmark.application.dto.request.BookmarkUpdateRequest;
import leets.bookmark.domain.bookmark.application.dto.response.BookmarkFullResponse;
import leets.bookmark.domain.bookmark.application.dto.response.BookmarkPreviewResponse;

import leets.bookmark.domain.bookmark.application.dto.request.BookmarkSearchRequest;
Expand All @@ -15,7 +16,7 @@

@Service
public interface BookmarkUseCase {
Slice<BookmarkResponse> getFilteredBookmarks(Long userId, BookmarkSearchRequest request);
Slice<BookmarkFullResponse> getFilteredBookmarks(Long userId, BookmarkSearchRequest request);

void delete(Long userId, Long bookmarkId);

Expand All @@ -26,4 +27,6 @@ public interface BookmarkUseCase {
List<BookmarkPreviewResponse> extractPreviewFromUrl(String url);

List<BookmarkPlatformResponse> getAllPlatforms(Long userId);

BookmarkFullResponse findBookmark(Long userId, Long bookmarkId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import leets.bookmark.domain.bookmark.application.dto.request.BookmarkSearchCondition;
import leets.bookmark.domain.bookmark.application.dto.request.CategoryTagRequest;
import leets.bookmark.domain.bookmark.application.dto.response.BookmarkFullResponse;
import leets.bookmark.domain.bookmark.application.dto.response.BookmarkPreviewResponse;
import leets.bookmark.domain.bookmark.application.dto.response.BookmarkPlatformResponse;
import leets.bookmark.domain.bookmark.application.exception.TagCategoryMismatchException;
Expand All @@ -23,6 +24,7 @@
import leets.bookmark.domain.file.application.dto.response.FileResponse;
import leets.bookmark.domain.file.application.mapper.FileMapper;
import leets.bookmark.domain.file.application.usecase.FileUseCase;
import leets.bookmark.domain.notification.application.dto.response.NotificationResponse;
import leets.bookmark.domain.notification.domain.service.NotificationDeleteService;
import leets.bookmark.domain.notification.domain.service.NotificationGetService;
import leets.bookmark.domain.user.domain.entity.User;
Expand Down Expand Up @@ -66,6 +68,7 @@ public class BookmarkUseCaseImpl implements BookmarkUseCase {
private final FileUseCase fileUseCase;
private final NotificationDeleteService notificationDeleteService;
private final NotificationGetService notificationGetService;
private final NotificationUseCase notificationUseCase;

private final FileMapper fileMapper;

Expand All @@ -74,7 +77,20 @@ public class BookmarkUseCaseImpl implements BookmarkUseCase {

@Override
@Transactional(readOnly = true)
public Slice<BookmarkResponse> getFilteredBookmarks(Long userId, BookmarkSearchRequest request) {
public BookmarkFullResponse findBookmark(Long userId, Long bookmarkId){
User user = userGetService.findById(userId);
Bookmark bookmark = bookmarkGetService.getBookmarkById(bookmarkId);

validateBookmarkOwner(user.getId(), bookmark);

FileResponse fileResponse = fileMapper.toFileResponse(bookmark.getFile());
NotificationResponse notificationResponse = notificationUseCase.getNotification(user, bookmark);
return bookmarkMapper.toFullResponse(bookmark, bookmarkGetService.getMappingsByBookmark(bookmark), fileResponse, notificationResponse);
}

@Override
@Transactional(readOnly = true)
public Slice<BookmarkFullResponse> getFilteredBookmarks(Long userId, BookmarkSearchRequest request) {
User user = userGetService.findById(userId);

Pageable pageable = PageRequest.of(request.page(),
Expand Down Expand Up @@ -134,7 +150,9 @@ public Slice<BookmarkResponse> getFilteredBookmarks(Long userId, BookmarkSearchR

return bookmarks.map(bookmark -> {
FileResponse fileResponse = fileMapper.toFileResponse(bookmark.getFile());
return bookmarkMapper.toResponse(bookmark, bookmarkGetService.getMappingsByBookmark(bookmark), fileResponse);
NotificationResponse notificationResponse = notificationUseCase.getNotification(user, bookmark);
return bookmarkMapper.toFullResponse(bookmark, bookmarkGetService.getMappingsByBookmark(bookmark),
fileResponse, notificationResponse);
}
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
import org.springframework.data.domain.SliceImpl;
import org.springframework.stereotype.Repository;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
Expand All @@ -30,25 +32,18 @@ public class BookmarkRepositoryImpl implements BookmarkRepositoryCustom {

private final QBookmark bookmark = QBookmark.bookmark;
private final QBookmarkTagMapping tagMapping = QBookmarkTagMapping.bookmarkTagMapping;
private final QTag tag = QTag.tag;
private final QCategory category = QCategory.category;
private final QFile file = QFile.file;

@Override
public Slice<Bookmark> searchWithFilters(Long userId, BookmarkSearchCondition condition, Pageable pageable) {

Slice<Long> idSlice = findBookmarkIds(userId, condition, pageable);

List<Bookmark> bookmarks = findBookmarksWithAssociations(idSlice.getContent());

return new SliceImpl<>(bookmarks, pageable, idSlice.hasNext());
return findBookmarkIds(userId, condition, pageable);
}

public Slice<Long> findBookmarkIds(Long userId, BookmarkSearchCondition condition, Pageable pageable) {
public Slice<Bookmark> findBookmarkIds(Long userId, BookmarkSearchCondition condition, Pageable pageable) {
BooleanBuilder builder = buildCondition(userId, condition);

List<Long> ids = queryFactory
.select(bookmark.id)
List<Bookmark> bookmarks = queryFactory
.selectDistinct(bookmark)
.from(tagMapping)
.leftJoin(tagMapping.bookmark, bookmark)
.where(builder)
Expand All @@ -57,24 +52,10 @@ public Slice<Long> findBookmarkIds(Long userId, BookmarkSearchCondition conditio
.limit(pageable.getPageSize() + 1)
.fetch();

boolean hasNext = ids.size() > pageable.getPageSize();
if (hasNext) ids.remove(pageable.getPageSize());

return new SliceImpl<>(ids, pageable, hasNext);
}
boolean hasNext = bookmarks.size() > pageable.getPageSize();
if (hasNext) bookmarks.remove(pageable.getPageSize());

public List<Bookmark> findBookmarksWithAssociations(List<Long> ids) {
if (ids.isEmpty()) return List.of();

return queryFactory
.select(bookmark)
.distinct()
.from(tagMapping)
.join(tagMapping.bookmark, bookmark)
.leftJoin(bookmark.category, category).fetchJoin()
.leftJoin(bookmark.file, file).fetchJoin()
.where(bookmark.id.in(ids))
.fetch();
return new SliceImpl<>(bookmarks, pageable, hasNext);
}

private BooleanBuilder buildCondition(Long userId, BookmarkSearchCondition condition) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import leets.bookmark.domain.bookmark.application.dto.request.BookmarkSearchRequest;
import leets.bookmark.domain.bookmark.application.dto.request.BookmarkSaveRequest;
import leets.bookmark.domain.bookmark.application.dto.request.BookmarkUpdateRequest;
import leets.bookmark.domain.bookmark.application.dto.response.BookmarkFullResponse;
import leets.bookmark.domain.notification.application.usecase.NotificationUseCase;
import leets.bookmark.global.auth.annotation.CurrentUser;
import leets.bookmark.global.common.response.CommonResponse;
Expand All @@ -25,12 +26,19 @@ public class BookmarkController {
private final BookmarkUseCase bookmarkUseCase;
private final NotificationUseCase notificationUseCase;

@GetMapping("/{bookmarkId}")
@Operation(summary = "북마크 단일 조회 API", description = "북마크를 조회합니다.")
public CommonResponse<BookmarkFullResponse> getBookmark(@CurrentUser Long userId, @PathVariable Long bookmarkId) {
BookmarkFullResponse response = bookmarkUseCase.findBookmark(userId, bookmarkId);
return CommonResponse.createSuccess(BOOKMARK_FIND_SUCCESS.getMessage(), response);
}

@PostMapping("/search")
@Operation(summary = "북마크 필터링 API")
public CommonResponse<Slice<BookmarkResponse>> getFilteredBookmarks(@CurrentUser Long userId,
public CommonResponse<Slice<BookmarkFullResponse>> getFilteredBookmarks(@CurrentUser Long userId,
@RequestBody @Valid BookmarkSearchRequest bookmarkSearchRequest) {
Slice<BookmarkResponse> responses = bookmarkUseCase.getFilteredBookmarks(userId, bookmarkSearchRequest);
return CommonResponse.createSuccess(BOOKMARK_FILTER_SUCCESS.getMessage(), responses);
Slice<BookmarkFullResponse> responses = bookmarkUseCase.getFilteredBookmarks(userId, bookmarkSearchRequest);
return CommonResponse.createSuccess(BOOKMARK_FIND_SUCCESS.getMessage(), responses);
}

@PostMapping()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
@Getter
@AllArgsConstructor
public enum BookmarkResponseMessage {

BOOKMARK_FIND_SUCCESS("북마크 단일 조회에 성공했습니다"),
BOOKMARK_SEARCH_SUCCESS("북마크 검색에 성공했습니다."),
BOOKMARK_MEMO_SEARCH_SUCCESS("북마크 메모 검색에 성공했습니다."),
BOOKMARK_FILTER_SUCCESS("북마크 필터링에 성공했습니다."),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@

import lombok.Builder;

import java.time.LocalDateTime;

@Builder
public record FileResponse(
Long fileId,
String fileName,
String fileUrl
String fileUrl,
LocalDateTime createdAt,
LocalDateTime updatedAt
) {}
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,11 @@ public File toFile(User user, Bookmark bookmark, FileSaveRequest fileSaveRequest

public FileResponse toFileResponse(File file){
return FileResponse.builder()
.fileId(file.getId())
.fileUrl(file.getFileUrl())
.fileName(file.getFileName())
.createdAt(file.getCreatedAt())
.updatedAt(file.getUpdatedAt())
.build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ public class NotificationUseCase {

private final UserGetService userGetService;

@Transactional(readOnly = true)
public NotificationResponse getNotification(User user, Bookmark bookmark) {
Optional<Notification> notification = notificationGetService.findByBookmarkId(bookmark.getId());

notification.ifPresent(value -> validateNotificationOwner(user, value));
return notification
.map(notificationMapper::toNotificationResponse)
.orElse(null);
}

@Transactional(readOnly = true)
public NotificationResponse getNotification(Long userId, Long bookmarkId) {
User user = userGetService.findById(userId);
Expand Down