Skip to content

Commit

Permalink
[FEAT] 북마크 서비스 구현 (#81)
Browse files Browse the repository at this point in the history
- BookmarkService
- BookmarkRepository
- BookmarkDetailRepository
  • Loading branch information
Gyaak authored Aug 17, 2024
1 parent f6ee4bd commit 86d054f
Show file tree
Hide file tree
Showing 14 changed files with 222 additions and 46 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.talkka.server.bookmark.dao;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;

public interface BookmarkDetailRepository extends JpaRepository<BookmarkDetailEntity, Long> {
List<BookmarkDetailEntity> findByBookmarkId(Long bookmarkId);

List<BookmarkDetailEntity> deleteByBookmarkId(Long bookmarkId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import com.talkka.server.bookmark.dto.BookmarkReqDto;
import com.talkka.server.user.dao.UserEntity;

import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.EntityListeners;
Expand Down Expand Up @@ -43,9 +45,9 @@ public class BookmarkEntity {
@JoinColumn(name = "user_id")
private UserEntity user;

@OneToMany(mappedBy = "bookmark")
@OneToMany(mappedBy = "bookmark", cascade = CascadeType.ALL, orphanRemoval = true)
@ToString.Exclude
private List<BookmarkDetailEntity> bookmarkDetails;
private List<BookmarkDetailEntity> details;

@Column(name = "created_at", nullable = false)
@CreatedDate
Expand All @@ -54,4 +56,11 @@ public class BookmarkEntity {
@LastModifiedDate
@Column(name = "updated_at", nullable = false)
private LocalDateTime updatedAt;

public void updateBookmark(BookmarkReqDto dto) {
this.name = dto.name();
this.details = dto.details().stream()
.map(detail -> detail.toEntity(this))
.toList();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.talkka.server.bookmark.dao;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;

public interface BookmarkRepository extends JpaRepository<BookmarkEntity, Long> {
List<BookmarkEntity> findByUserId(Long userId);

boolean existsByIdAndUserId(Long bookmarkId, Long userId);
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package com.talkka.server.bookmark.dao.dto;
package com.talkka.server.bookmark.dto;

import com.talkka.server.bookmark.dao.BookmarkDetailEntity;
import com.talkka.server.bookmark.dao.BookmarkEntity;
import com.talkka.server.bookmark.enums.TransportType;
import com.talkka.server.subway.enums.Updown;

public record BookmarkDetailCreateDto(
public record BookmarkDetailReqDto(
Integer seq,
TransportType type,
String type,
Long subwayStationId,
Updown subwayUpdown,
Long busRouteStationId
Expand All @@ -18,7 +18,7 @@ public BookmarkDetailEntity toEntity(
return BookmarkDetailEntity.builder()
.seq(seq)
.bookmark(bookmark)
.type(type)
.type(TransportType.valueOf(type))
.subwayStationId(subwayStationId)
.subwayUpdown(subwayUpdown)
.busRouteStationId(busRouteStationId)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
package com.talkka.server.bookmark.dao.dto;
package com.talkka.server.bookmark.dto;

import com.talkka.server.bookmark.dao.BookmarkDetailEntity;
import com.talkka.server.bookmark.enums.TransportType;
import com.talkka.server.subway.enums.Updown;

public record BookmarkDetailRespDto(
Integer seq,
TransportType type,
String type,
Long subwayStationId,
Updown subwayUpdown,
Long busRouteStationId
) {
public static BookmarkDetailRespDto of(BookmarkDetailEntity entity) {
return new BookmarkDetailRespDto(
entity.getSeq(),
entity.getType(),
entity.getType().getType(),
entity.getSubwayStationId(),
entity.getSubwayUpdown(),
entity.getBusRouteStationId()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.talkka.server.bookmark.dto;

import java.util.ArrayList;
import java.util.List;

import com.talkka.server.bookmark.dao.BookmarkEntity;
import com.talkka.server.user.dao.UserEntity;

public record BookmarkReqDto(
String name,
List<BookmarkDetailReqDto> details
) {
public BookmarkEntity toEntity(UserEntity user) {
return BookmarkEntity.builder()
.name(name)
.user(user)
.details(new ArrayList<>())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.talkka.server.bookmark.dto;

import java.util.List;

import com.talkka.server.bookmark.dao.BookmarkEntity;
import com.talkka.server.user.dto.UserDto;
import com.talkka.server.user.dto.UserRespDto;

public record BookmarkRespDto(
Long id,
String name,
UserRespDto user,
List<BookmarkDetailRespDto> details
) {
public static BookmarkRespDto of(BookmarkEntity bookmark) {
return new BookmarkRespDto(
bookmark.getId(),
bookmark.getName(),
UserRespDto.of(UserDto.of(bookmark.getUser())),
bookmark.getDetails().stream()
.map(BookmarkDetailRespDto::of)
.toList()
);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
package com.talkka.server.bookmark.enums;

import com.talkka.server.bookmark.exception.enums.InvalidTransportTypeEnumException;

import lombok.Getter;

@Getter
public enum TransportType {
BUS, SUBWAY
BUS("bus"), SUBWAY("subway");

private final String type;

TransportType(String type) {
this.type = type;
}

public static TransportType valueOfEnumString(String enumValue) {
try {
return TransportType.valueOf(enumValue);
} catch (IllegalArgumentException exception) {
throw new InvalidTransportTypeEnumException();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.talkka.server.bookmark.exception;

public class BookmarkNotFoundException extends RuntimeException {
private static final String MESSAGE = "존재하지 않는 북마크 입니다.";

public BookmarkNotFoundException() {
super(MESSAGE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.talkka.server.bookmark.exception;

public class BookmarkUserNotFoundException extends RuntimeException {
private static final String MESSAGE = "존재하지 않는 사용자 입니다.";

public BookmarkUserNotFoundException() {
super(MESSAGE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.talkka.server.bookmark.exception.enums;

import com.talkka.server.common.exception.InvalidTypeException;

public class InvalidTransportTypeEnumException extends InvalidTypeException {
private static final String MESSAGE = "잘못된 교통수단 구분입니다.";

public InvalidTransportTypeEnumException() {
super(MESSAGE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package com.talkka.server.bookmark.service;

import java.util.List;

import org.springframework.stereotype.Service;

import com.talkka.server.bookmark.dao.BookmarkDetailRepository;
import com.talkka.server.bookmark.dao.BookmarkEntity;
import com.talkka.server.bookmark.dao.BookmarkRepository;
import com.talkka.server.bookmark.dto.BookmarkReqDto;
import com.talkka.server.bookmark.dto.BookmarkRespDto;
import com.talkka.server.bookmark.exception.BookmarkNotFoundException;
import com.talkka.server.bookmark.exception.BookmarkUserNotFoundException;
import com.talkka.server.common.validator.ContentAccessValidator;
import com.talkka.server.review.exception.ContentAccessException;
import com.talkka.server.user.dao.UserEntity;
import com.talkka.server.user.dao.UserRepository;

import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class BookmarkService {
private final BookmarkRepository bookmarkRepository;
private final BookmarkDetailRepository bookmarkDetailRepository;
private final UserRepository userRepository;
private final ContentAccessValidator contentAccessValidator;

@Transactional
public BookmarkRespDto createBookmark(BookmarkReqDto dto, Long userId) throws BookmarkUserNotFoundException {
UserEntity user = userRepository.findById(userId).orElseThrow(BookmarkUserNotFoundException::new);
BookmarkEntity bookmark = dto.toEntity(user);
dto.details().stream()
.map(detail -> detail.toEntity(bookmark))
.forEach(bookmark.getDetails()::add);
return BookmarkRespDto.of(bookmarkRepository.save(bookmark));
}

public BookmarkRespDto getByBookmarkId(Long id) throws BookmarkNotFoundException {
BookmarkEntity bookmark = bookmarkRepository.findById(id).orElseThrow(BookmarkUserNotFoundException::new);
return BookmarkRespDto.of(bookmark);
}

public List<BookmarkRespDto> getByUserId(Long userId) {
return bookmarkRepository.findByUserId(userId).stream()
.map(BookmarkRespDto::of)
.toList();
}

@Transactional
public BookmarkRespDto updateBookmark(BookmarkReqDto dto, Long bookmarkId, Long userId) throws
BookmarkUserNotFoundException,
BookmarkNotFoundException,
ContentAccessException {

UserEntity user = userRepository.findById(userId).orElseThrow(BookmarkUserNotFoundException::new);
BookmarkEntity bookmark = bookmarkRepository.findById(bookmarkId)
.orElseThrow(BookmarkUserNotFoundException::new);

// 작성자거나 관리자가 아니면 ContentAccessException 발생
contentAccessValidator.validateOwnerContentAccess(user.getId(), user.getGrade(), bookmark.getId());

// 기존 북마크 상세를 전부 지우고 전체를 새로 저장함
bookmarkDetailRepository.deleteByBookmarkId(bookmarkId);
bookmark.updateBookmark(dto);

return BookmarkRespDto.of(bookmarkRepository.save(bookmark));
}

@Transactional
public Long deleteBookmark(Long bookmarkId, Long userId) throws
BookmarkUserNotFoundException,
BookmarkNotFoundException {

UserEntity user = userRepository.findById(userId).orElseThrow(BookmarkUserNotFoundException::new);
BookmarkEntity bookmark = bookmarkRepository.findById(bookmarkId)
.orElseThrow(BookmarkUserNotFoundException::new);

// 작성자거나 관리자가 아니면 ContentAccessException 발생
contentAccessValidator.validateOwnerContentAccess(user.getId(), user.getGrade(), bookmark.getId());

// 북마크와 북마크 상세를 삭제
bookmarkRepository.delete(bookmark);

return bookmarkId;
}
}

0 comments on commit 86d054f

Please sign in to comment.