Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
7811ec9
feat: 공통 엔티티 작성
AnJungGeon Apr 1, 2025
e703b44
feat: 댓글 엔티티 작성
AnJungGeon Apr 1, 2025
fe2f76a
feat: 게시글 엔티티 작성
AnJungGeon Apr 1, 2025
9a51870
feat: 댓글 컨트롤러 생성
AnJungGeon Apr 1, 2025
be83659
feat: 게시글 컨트롤러 생성
AnJungGeon Apr 1, 2025
26cb437
feat: 댓글 서비스 생성
AnJungGeon Apr 1, 2025
6d2d14a
feat: 게시글 서비스 생성
AnJungGeon Apr 1, 2025
e477bdf
feat: 댓글 repositroy 생성
AnJungGeon Apr 1, 2025
905afda
feat: 게시글 repositroy 생성
AnJungGeon Apr 1, 2025
ad60660
feat: 게시글 생성 요청 dto 생성
AnJungGeon Apr 1, 2025
074a422
feat: 게시글 응답 dto 생성
AnJungGeon Apr 1, 2025
005036b
feat: 게시글 생성 컨트롤러 작성
AnJungGeon Apr 1, 2025
8bf8807
feat: JpaAuditing 어노테이션 추가
AnJungGeon Apr 1, 2025
03803d0
feat: BaseEntity에 MappedSuperclass 추가
AnJungGeon Apr 1, 2025
98a2834
feat: 게시글 생성 비즈니스 로직 작성
AnJungGeon Apr 1, 2025
6f0df64
feat: 댓글 엔티티 제약 조건 추가 및 수정
AnJungGeon Apr 1, 2025
2e32f3c
feat: 게시글 작성 repository 추가
AnJungGeon Apr 1, 2025
8e8df83
feat: 게시글 등록 httpClient 작성
AnJungGeon Apr 1, 2025
b074a7b
feat: 게시글 조회 httpClient 작성
AnJungGeon Apr 1, 2025
ce85654
feat: 게시글 조회 응답 dto 생성
AnJungGeon Apr 1, 2025
8e3963b
feat: 게시글 조회 요청 메소드 작성
AnJungGeon Apr 1, 2025
9369de2
feat: 게시글 조회 비즈니스 로직 작성
AnJungGeon Apr 1, 2025
fbd045e
feat: 게시글 등록 예외처리 수정
AnJungGeon Apr 1, 2025
0fc888a
feat: 댓글 생성 요청 dto 생성
AnJungGeon Apr 1, 2025
d8054ef
feat: 댓글 api 응답 dto 생성
AnJungGeon Apr 1, 2025
6c65ee2
feat: 댓글 생성 요청 메소드 작성
AnJungGeon Apr 1, 2025
7317701
feat: 댓글 생성 비즈니스 로직 작성
AnJungGeon Apr 1, 2025
bc33101
feat: 게시글 서비스 접근제어자 추가
AnJungGeon Apr 1, 2025
acd2113
feat: 댓글 생성 repository 메소드 작성
AnJungGeon Apr 1, 2025
10f0f1c
feat: 댓글 생성 httpClient 추가
AnJungGeon Apr 1, 2025
8192547
feat: 게시글 조회 시 댓글 리스트로 추가
AnJungGeon Apr 1, 2025
dcb7653
feat: 게시글 조회 시 댓글 리스트로 추가
AnJungGeon Apr 1, 2025
a3b7750
feat: 게시글 수정 요청, 응답 dto 생성
AnJungGeon Apr 1, 2025
dc1256a
feat: 게시글 수정 비즈니스 로직 작성
AnJungGeon Apr 1, 2025
4a7dce2
feat: 게시글 조회 시 조건 추가
AnJungGeon Apr 1, 2025
7ba28ef
feat: 게시글 엔티티 수정 메소드 추가
AnJungGeon Apr 1, 2025
f824210
feat: 게시글 수정 요청 메소드 작성
AnJungGeon Apr 1, 2025
21653d9
feat: 댓글 응답 dto 필드 수정
AnJungGeon Apr 1, 2025
934a3e6
feat: 게시글 수정 httpClient 생성
AnJungGeon Apr 1, 2025
952d6a2
feat: BaseEntity 삭제 메소드 생성
AnJungGeon Apr 1, 2025
3fee10c
feat: 게시글 삭제 요청 메소드 작성
AnJungGeon Apr 1, 2025
6d5cbe3
feat: 게시글 삭제 비즈니스 로직 작성
AnJungGeon Apr 1, 2025
a86b0e4
feat: 댓글 수정 요청 dto 생성
AnJungGeon Apr 1, 2025
3995013
feat: 댓글 entity 수정 메소드 추가
AnJungGeon Apr 1, 2025
a205e53
feat: 댓글 수정 요청 메소드 작성
AnJungGeon Apr 1, 2025
39c7bfc
feat: 댓글 삭제여부 조회 메소드 추가
AnJungGeon Apr 1, 2025
8fe6e57
feat: 댓글 수정 비즈니스 로직 작성
AnJungGeon Apr 1, 2025
3292e7b
feat: 게시글 삭제 테스트
AnJungGeon Apr 1, 2025
29f56a0
feat: 댓글 수정 테스트
AnJungGeon Apr 1, 2025
56f3286
feat: 댓글 삭제 요청 메소드 작성
AnJungGeon Apr 1, 2025
ee2b4af
feat: 삭제 댓글 조회 메소드 작성
AnJungGeon Apr 1, 2025
09c649d
feat: 댓글 삭제, 댓글 조회 비즈니스 로직 추가했습니다
AnJungGeon Apr 1, 2025
5ea125f
feat: 댓글 삭제 테스트
AnJungGeon Apr 1, 2025
ba1881a
fix: 게시글 조회 비즈니스 로직 수정
AnJungGeon Apr 1, 2025
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
3 changes: 3 additions & 0 deletions src/main/java/io/sparta/board/BoardApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@SpringBootApplication
@EnableJpaAuditing
public class BoardApplication {

public static void main(String[] args) {
Expand Down
31 changes: 31 additions & 0 deletions src/main/java/io/sparta/board/common/BaseEntity.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package io.sparta.board.common;

import jakarta.persistence.Column;
import jakarta.persistence.EntityListeners;
import jakarta.persistence.MappedSuperclass;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;

@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public class BaseEntity {

@Column(name = "deleted", nullable = false)
private boolean deleted = false;

@CreatedDate
@Column(name = "created_at", nullable = false)
private LocalDateTime createdAt;

@LastModifiedDate
@Column(name = "updated_at", nullable = false)
private LocalDateTime updatedAt;

public void setDeleted(boolean deleted) {
this.deleted = true;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package io.sparta.board.domain.comment.controller;

import io.sparta.board.domain.comment.dto.requeset.CommentCreateRequestDto;
import io.sparta.board.domain.comment.dto.requeset.CommentUpdateRequestDto;
import io.sparta.board.domain.comment.dto.response.CommentResponseDto;
import io.sparta.board.domain.comment.service.CommentService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.UUID;

@RestController
@RequestMapping("/api/v1/comment")
@RequiredArgsConstructor
public class CommentCotroller {

private final CommentService commentService;

//댓글 등록
@PostMapping("/{postId}")
public ResponseEntity<CommentResponseDto> createComment(
@RequestBody CommentCreateRequestDto request,
@PathVariable UUID postId
){
CommentResponseDto response = commentService.createComment(request, postId);

return ResponseEntity.status(HttpStatus.CREATED).body(response);
}

//댓글 수정
@PatchMapping("/{id}")
public ResponseEntity<CommentResponseDto> updateComment(
@PathVariable UUID id,
@RequestBody CommentUpdateRequestDto request
){
if(id == null) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}

CommentResponseDto response = commentService.updateComment(id, request);

return ResponseEntity.status(HttpStatus.OK).body(response);
}

//댓글 삭제
@DeleteMapping("/{id}")
public ResponseEntity<CommentResponseDto> deleteComment(
@PathVariable UUID id
){

if(id == null) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}

commentService.deleteComment(id);

return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
}



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package io.sparta.board.domain.comment.dto.requeset;

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class CommentCreateRequestDto {

private String comment;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.sparta.board.domain.comment.dto.requeset;

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class CommentUpdateRequestDto {
private String content;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package io.sparta.board.domain.comment.dto.response;

import lombok.Builder;
import lombok.Getter;

import java.util.UUID;

@Getter
@Builder
public class CommentResponseDto {

private UUID id;
private UUID postId;
private String content;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package io.sparta.board.domain.comment.service;

import io.sparta.board.domain.comment.dto.requeset.CommentCreateRequestDto;
import io.sparta.board.domain.comment.dto.requeset.CommentUpdateRequestDto;
import io.sparta.board.domain.comment.dto.response.CommentResponseDto;
import io.sparta.board.model.comment.entity.Comment;
import io.sparta.board.model.comment.repository.CommentReposiroy;
import io.sparta.board.model.post.entity.Post;
import io.sparta.board.model.post.repository.PostRepository;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

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

@Service
@RequiredArgsConstructor
public class CommentService {

private final CommentReposiroy commentReposiroy;

private final PostRepository postRepository;

@Transactional
public CommentResponseDto createComment(
CommentCreateRequestDto request,
UUID postId) {

Post post = postRepository.findByIdAndDeletedIsFalse(postId)
.orElseThrow(() -> new IllegalArgumentException("게시글 없음"));

Comment comment = Comment.builder()
.content(request.getComment())
.post(post)
.build();

Comment saveComment = commentReposiroy.save(comment);

return CommentResponseDto.builder()
.id(saveComment.getId())
.postId(saveComment.getPost().getId())
.content(saveComment.getContent())
.build();
}

public CommentResponseDto updateComment(UUID id, CommentUpdateRequestDto request) {

Comment existComment = commentReposiroy.findByIdAndDeletedIsFalse(id)
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 댓글"));


existComment.UpdateComment(request.getContent());

Comment updateComment = commentReposiroy.save(existComment);

return CommentResponseDto.builder()
.id(updateComment.getId())
.postId(updateComment.getPost().getId())
.content(updateComment.getContent())
.build();
}

public void deleteComment(UUID id) {

Comment existComment = commentReposiroy.findByIdAndDeletedIsFalse(id)
.orElseThrow(() -> new IllegalArgumentException("이미 삭제된 댓글"));

existComment.setDeleted(true);

commentReposiroy.save(existComment);

}

public List<Comment> getPostComment(UUID id) {

List<Comment> comments = new ArrayList<>();
List<Comment> commentList = commentReposiroy.findByPostIdAndDeletedIsFalse(id);

for (Comment comment : commentList) {
comments.add(comment);
}

return comments;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package io.sparta.board.domain.post.controller;

import io.sparta.board.domain.post.dto.request.PostCreateRequestDto;
import io.sparta.board.domain.post.dto.request.PostUpdateRequestDto;
import io.sparta.board.domain.post.dto.response.GetPostResponseDto;
import io.sparta.board.domain.post.dto.response.PostResponseDto;
import io.sparta.board.domain.post.dto.response.PostUpdateResponse;
import io.sparta.board.domain.post.service.PostServcie;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.UUID;

@RestController
@RequestMapping("/api/v1/post")
@RequiredArgsConstructor
public class PostController {

private final PostServcie postService;
//게시글 작성
@PostMapping
public ResponseEntity<PostResponseDto> createPost(
@RequestBody PostCreateRequestDto request
) {

if(request.getTitle() == null || request.getTitle().isEmpty()) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}

if(request.getContent() == null || request.getContent().isEmpty()) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}

PostResponseDto response = postService.createPost(request);

return ResponseEntity.status(HttpStatus.CREATED).body(response);
}


//게시글 단건 조회
@GetMapping("/{id}")
public ResponseEntity<GetPostResponseDto> getPost(
@PathVariable UUID id
){
if(id == null) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}

GetPostResponseDto responseDto = postService.getPost(id);

return ResponseEntity.status(HttpStatus.OK).body(responseDto);
}

//게시글 수정
@PatchMapping("/{id}")
public ResponseEntity<PostUpdateResponse> updatePost(
@PathVariable UUID id,
@RequestBody PostUpdateRequestDto request
){
if(id == null) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();

}

PostUpdateResponse responseDto = postService.updatePost(id, request);

return ResponseEntity.status(HttpStatus.OK).body(responseDto);
}

//게시글 삭제
@DeleteMapping("/{id}")
public ResponseEntity<?> deletePost(
@PathVariable UUID id
){
if(id == null) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}

postService.deletePost(id);

return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
}



}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.sparta.board.domain.post.dto.request;

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class PostCreateRequestDto {

private String title;
private String content;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.sparta.board.domain.post.dto.request;

import lombok.Builder;
import lombok.Getter;

@Getter
@Builder
public class PostUpdateRequestDto {

private String title;
private String content;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.sparta.board.domain.post.dto.response;

import io.sparta.board.model.comment.entity.Comment;
import lombok.Builder;
import lombok.Getter;

import java.util.List;
import java.util.UUID;

@Getter
@Builder
public class GetPostResponseDto {
private UUID id;
private String title;
private String content;
private List<String> comments;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.sparta.board.domain.post.dto.response;

import lombok.Builder;
import lombok.Getter;

import java.util.UUID;

@Getter
@Builder
public class PostResponseDto {
private UUID id;
private String title;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.sparta.board.domain.post.dto.response;

import lombok.Builder;
import lombok.Getter;

import java.util.UUID;

@Getter
@Builder
public class PostUpdateResponse {
private UUID id;
private String title;
private String content;
}
Loading