Skip to content

Commit

Permalink
feat: 내 글 관리 기능 구현 (#83)
Browse files Browse the repository at this point in the history
* [#56] feat: 포스트 생성, 수정, 삭제 endpoint prefix로 /manage 설정

* [#56] feat: 기존 블로그 Id 사용 로직을 모두 이름을 사용하도록 변경

* [#56] feat: 내 글 관리 목록 조회 기능 구현

* [#56] feat: 내 관리 글 단일 조회 기능 구현

* test: 각 인수테스트에서 AcceptanceTest 상속받도록 수정
  • Loading branch information
shin-mallang authored Nov 20, 2023
1 parent 4595eaa commit 98b50d3
Show file tree
Hide file tree
Showing 65 changed files with 1,478 additions and 729 deletions.
4 changes: 4 additions & 0 deletions src/main/java/com/mallang/blog/domain/Blog.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,8 @@ public Blog(String name, Member owner) {
public void open(BlogValidator blogValidator) {
blogValidator.validateOpen(this.owner.getId(), this.name);
}

public String getName() {
return name.getValue();
}
}
10 changes: 5 additions & 5 deletions src/main/java/com/mallang/blog/domain/BlogName.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,16 @@ public class BlogName {

private static final Pattern pattern = Pattern.compile("^(?![-_])(?!.*--)[a-z0-9-_]{4,32}(?<![-_])$");

@Column(nullable = false, unique = true)
private String name;
@Column(name = "name", nullable = false, unique = true)
private String value;

protected BlogName() {
}

public BlogName(String name) {
name = name.strip();
validateDomainName(name);
this.name = name;
this.value = name;
}

private void validateDomainName(String name) {
Expand All @@ -39,11 +39,11 @@ public boolean equals(Object o) {
if (!(o instanceof BlogName blogName)) {
return false;
}
return Objects.equals(getName(), blogName.getName());
return Objects.equals(getValue(), blogName.getValue());
}

@Override
public int hashCode() {
return Objects.hash(getName());
return Objects.hash(getValue());
}
}
20 changes: 14 additions & 6 deletions src/main/java/com/mallang/blog/domain/BlogRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,29 @@
import com.mallang.blog.exception.NotFoundBlogException;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface BlogRepository extends JpaRepository<Blog, Long> {

@Override
default Blog getById(Long id) {
return findById(id).orElseThrow(NotFoundBlogException::new);
default Blog getByName(String blogName) {
return findByName(blogName).orElseThrow(NotFoundBlogException::new);
}

default Blog getByIdAndOwnerId(Long id, Long ownerId) {
return findByIdAndOwnerId(id, ownerId)
@Query("SELECT b FROM Blog b WHERE b.name.value = :blogName")
Optional<Blog> findByName(String blogName);

default Blog getByNameAndOwnerId(String blogName, Long ownerId) {
return findByNameAndOwnerId(blogName, ownerId)
.orElseThrow(() ->
new NotFoundBlogException("존재하지 않는 블로그거나, 해당 사용자의 블로그가 아닙니다."));
}

Optional<Blog> findByIdAndOwnerId(Long id, Long ownerId);
@Query("SELECT b FROM Blog b WHERE b.name.value = :blogName AND b.owner.id = :ownerId")
Optional<Blog> findByNameAndOwnerId(
@Param("blogName") String blogName,
@Param("ownerId") Long ownerId
);

boolean existsByName(BlogName name);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class CategoryService {

public Long create(CreateCategoryCommand command) {
Member member = memberRepository.getById(command.memberId());
Blog blog = blogRepository.getByIdAndOwnerId(command.blogId(), command.memberId());
Blog blog = blogRepository.getByNameAndOwnerId(command.blogName(), command.memberId());
Category parentCategory = getParentCategory(command.parentCategoryId(), command.memberId());
Category category = Category.create(command.name(), member, blog, parentCategory, categoryValidator);
return categoryRepository.save(category).getId();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
@Builder
public record CreateCategoryCommand(
Long memberId,
Long blogId,
String blogName,
String name,
@Nullable Long parentCategoryId
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ public ResponseEntity<Void> delete(

@GetMapping
public ResponseEntity<List<CategoryData>> findAllByBlog(
@RequestParam(name = "blogId", required = true) Long blogId
@RequestParam(name = "blogName", required = true) String blogName
) {
List<CategoryData> result = categoryQueryService.findAllByBlogId(blogId);
List<CategoryData> result = categoryQueryService.findAllByBlogName(blogName);
return ResponseEntity.ok(result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@
import jakarta.annotation.Nullable;

public record CreateCategoryRequest(
Long blogId,
String blogName,
String name,
@Nullable Long parentCategoryId
) {

public CreateCategoryCommand toCommand(Long memberId) {
return CreateCategoryCommand.builder()
.name(name)
.blogId(blogId)
.blogName(blogName)
.memberId(memberId)
.parentCategoryId(parentCategoryId)
.build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class CategoryQueryService {

private final CategoryDataDao categoryDataDao;

public List<CategoryData> findAllByBlogId(Long blogId) {
return categoryDataDao.findAllByBlogId(blogId);
public List<CategoryData> findAllByBlogName(String blogName) {
return categoryDataDao.findAllByBlogName(blogName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ public class CategoryDataDao {

private final CategoryQuerySupport categoryQuerySupport;

public List<CategoryData> findAllByBlogId(Long blogId) {
return categoryQuerySupport.findAllRootByBlogId(blogId)
public List<CategoryData> findAllByBlogName(String blogName) {
return categoryQuerySupport.findAllRootByBlogName(blogName)
.stream()
.map(CategoryData::from)
.toList();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

public interface CategoryQuerySupport extends JpaRepository<Category, Long> {

Expand All @@ -13,6 +14,6 @@ default Category getById(Long id) {
return findById(id).orElseThrow(NotFoundCategoryException::new);
}

@Query("SELECT c FROM Category c WHERE c.blog.id = :blogId AND c.parent = null")
List<Category> findAllRootByBlogId(Long blogId);
@Query("SELECT c FROM Category c WHERE c.blog.name.value = :blogName AND c.parent = null")
List<Category> findAllRootByBlogName(@Param("blogName") String blogName);
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class PostService {

public Long create(CreatePostCommand command) {
Member member = memberRepository.getById(command.memberId());
Blog blog = blogRepository.getByIdAndOwnerId(command.blogId(), command.memberId());
Blog blog = blogRepository.getByNameAndOwnerId(command.blogName(), command.memberId());
Category category = getCategoryByIdAndOwnerIdIfPresent(command.categoryId(), command.memberId());
Long postIdInBlog = postOrderInBlogGenerator.generate(blog);
Post post = command.toPost(member, blog, category, postIdInBlog);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
@Builder
public record CreatePostCommand(
Long memberId,
Long blogId,
String blogName,
String title,
String content,
@Nullable String postThumbnailImageName,
Expand All @@ -26,13 +26,13 @@ public record CreatePostCommand(
) {
public Post toPost(Member member, Blog blog, Category category, Long postIdInBlog) {
return Post.builder()
.blog(blog)
.title(title)
.content(content)
.postThumbnailImageName(postThumbnailImageName)
.order(postIdInBlog)
.writer(member)
.visibilityPolish(new PostVisibilityPolicy(visibility, password))
.blog(blog)
.category(category)
.postIntro(new PostIntro(intro))
.tags(tags)
Expand Down
39 changes: 0 additions & 39 deletions src/main/java/com/mallang/post/presentation/PostController.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,18 @@

import static com.mallang.post.presentation.support.PostPresentationConstant.POST_PASSWORD_COOKIE;

import com.mallang.auth.presentation.support.Auth;
import com.mallang.auth.presentation.support.OptionalAuth;
import com.mallang.post.application.PostService;
import com.mallang.post.presentation.request.CreatePostRequest;
import com.mallang.post.presentation.request.DeletePostRequest;
import com.mallang.post.presentation.request.UpdatePostRequest;
import com.mallang.post.query.PostQueryService;
import com.mallang.post.query.data.PostDetailData;
import com.mallang.post.query.data.PostSearchCond;
import com.mallang.post.query.data.PostSimpleData;
import java.net.URI;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

Expand All @@ -32,37 +22,8 @@
@RestController
public class PostController {

private final PostService postService;
private final PostQueryService postQueryService;

@PostMapping
public ResponseEntity<Void> create(
@Auth Long memberId,
@RequestBody CreatePostRequest request
) {
Long id = postService.create(request.toCommand(memberId));
return ResponseEntity.created(URI.create("/posts/" + id)).build();
}

@PutMapping("/{id}")
public ResponseEntity<Void> update(
@PathVariable(name = "id") Long postId,
@Auth Long memberId,
@RequestBody UpdatePostRequest request
) {
postService.update(request.toCommand(memberId, postId));
return ResponseEntity.ok().build();
}

@DeleteMapping
public ResponseEntity<Void> delete(
@Auth Long memberId,
@RequestBody DeletePostRequest request
) {
postService.delete(request.toCommand(memberId));
return ResponseEntity.noContent().build();
}

@GetMapping("/{id}")
public ResponseEntity<PostDetailData> getById(
@OptionalAuth Long memberId,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.mallang.post.presentation;

import com.mallang.auth.presentation.support.Auth;
import com.mallang.post.application.PostService;
import com.mallang.post.presentation.request.CreatePostRequest;
import com.mallang.post.presentation.request.DeletePostRequest;
import com.mallang.post.presentation.request.UpdatePostRequest;
import com.mallang.post.query.PostManageQueryService;
import com.mallang.post.query.data.PostManageDetailData;
import com.mallang.post.query.data.PostManageSearchCond;
import com.mallang.post.query.data.PostManageSimpleData;
import java.net.URI;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequiredArgsConstructor
@RequestMapping("/manage/posts")
@RestController
public class PostManageController {

private final PostService postService;
private final PostManageQueryService postManageQueryService;

@PostMapping
public ResponseEntity<Void> create(
@Auth Long memberId,
@RequestBody CreatePostRequest request
) {
Long id = postService.create(request.toCommand(memberId));
return ResponseEntity.created(URI.create("/posts/" + id)).build();
}

@PutMapping("/{id}")
public ResponseEntity<Void> update(
@PathVariable(name = "id") Long postId,
@Auth Long memberId,
@RequestBody UpdatePostRequest request
) {
postService.update(request.toCommand(memberId, postId));
return ResponseEntity.ok().build();
}

@DeleteMapping
public ResponseEntity<Void> delete(
@Auth Long memberId,
@RequestBody DeletePostRequest request
) {
postService.delete(request.toCommand(memberId));
return ResponseEntity.noContent().build();
}

@GetMapping("/{id}")
public ResponseEntity<PostManageDetailData> getById(
@PathVariable(name = "id") Long postId,
@Auth Long memberId
) {
return ResponseEntity.ok(postManageQueryService.findById(memberId, postId));
}

@GetMapping
public ResponseEntity<List<PostManageSimpleData>> search(
@Auth Long memberId,
@ModelAttribute PostManageSearchCond cond
) {
return ResponseEntity.ok(postManageQueryService.search(memberId, cond));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import java.util.List;

public record CreatePostRequest(
Long blogId,
String blogName,
String title,
String content,
@Nullable String postThumbnailImageName,
Expand All @@ -20,7 +20,7 @@ public record CreatePostRequest(
public CreatePostCommand toCommand(Long memberId) {
return CreatePostCommand.builder()
.memberId(memberId)
.blogId(blogId)
.blogName(blogName)
.title(title)
.content(content)
.postThumbnailImageName(postThumbnailImageName)
Expand Down
28 changes: 28 additions & 0 deletions src/main/java/com/mallang/post/query/PostManageQueryService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.mallang.post.query;

import com.mallang.post.query.dao.PostManageDetailDataDao;
import com.mallang.post.query.dao.PostManageSimpleDataDao;
import com.mallang.post.query.data.PostManageDetailData;
import com.mallang.post.query.data.PostManageSearchCond;
import com.mallang.post.query.data.PostManageSimpleData;
import java.util.List;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@RequiredArgsConstructor
@Transactional(readOnly = true)
@Service
public class PostManageQueryService {

private final PostManageDetailDataDao postManageDetailDataDao;
private final PostManageSimpleDataDao postManageSimpleDataDao;

public PostManageDetailData findById(Long memberId, Long id) {
return postManageDetailDataDao.find(memberId, id);
}

public List<PostManageSimpleData> search(Long memberId, PostManageSearchCond cond) {
return postManageSimpleDataDao.search(memberId, cond);
}
}
Loading

0 comments on commit 98b50d3

Please sign in to comment.