Skip to content

Commit

Permalink
Merge pull request #13 from Alpha-mon/10-community-post
Browse files Browse the repository at this point in the history
10 community post
  • Loading branch information
megymj authored Sep 19, 2023
2 parents 50a61ca + c7a636f commit 26560c1
Show file tree
Hide file tree
Showing 10 changed files with 450 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
package org.ai.roboadvisor.domain.community.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.ai.roboadvisor.domain.community.dto.request.PostRequest;
import org.ai.roboadvisor.domain.community.dto.response.PostResponse;
import org.ai.roboadvisor.domain.community.service.PostService;
import org.ai.roboadvisor.global.common.dto.SuccessApiResponse;
import org.ai.roboadvisor.global.exception.CustomException;
import org.ai.roboadvisor.global.exception.ErrorCode;
import org.ai.roboadvisor.global.exception.SuccessCode;
import org.ai.roboadvisor.global.swagger_annotation.ApiResponse_Internal_Server_Error;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@Slf4j
@RequiredArgsConstructor
@Tag(name = "community] post", description = "게시글 작성, 수정, 삭제 API")
@RestController
@RequestMapping("/api/community/post")
public class PostController {
private final PostService postService;

private final int SUCCESS = 0;
private final int TIME_INPUT_INVALID = -1;
private final int INTERNAL_SERVER_ERROR = -100;

@Operation(summary = "게시글 작성", description = "게시글 작성 API")
@ApiResponse(responseCode = "201", description = """
정상 응답
data로 게시글 정보를 리턴하며, id는 게시글의 고유 번호이다.
""",
content = @Content(schema = @Schema(implementation = SuccessApiResponse.class),
examples = @ExampleObject(name = "example",
description = "정상 응답 예시",
value = """
{
"code": 201,
"message": "게시글이 정상적으로 등록되었습니다",
"data": {
"id": 3,
"type": "SHEEP",
"nickname": "testUser",
"content": "안녕하세요",
"time": "2023-09-17 23:44:33"
}
}
"""
)))
@ApiResponse(responseCode = "400", description = "시간 형식을 잘못 입력한 경우",
content = @Content(schema = @Schema(implementation = SuccessApiResponse.class),
examples = @ExampleObject(name = "example",
description = "시간 형식을 잘못 입력한 경우 예시",
value = """
{
"code": 400,
"message": "time 형식을 yyyy-MM-dd HH:mm:ss으로 작성해 주세요",
"data": null
}
"""
)))
@ApiResponse_Internal_Server_Error
@PostMapping()
public ResponseEntity<SuccessApiResponse<PostResponse>> savePost(@RequestBody PostRequest postRequest) {
return ResponseEntity.status(HttpStatus.CREATED)
.body(SuccessApiResponse.success(SuccessCode.POST_CREATED_SUCCESS,
postService.save(postRequest)));
}

@Operation(summary = "게시글 수정", description = "게시글 수정 API")
@ApiResponse(responseCode = "200", description = """
정상 응답
data로 게시글 정보를 리턴하며, id는 게시글의 고유 번호이다.
""",
content = @Content(schema = @Schema(implementation = SuccessApiResponse.class),
examples = @ExampleObject(name = "example",
description = "정상 응답 예시",
value = """
{
"code": 200,
"message": "게시글 수정이 정상적으로 처리되었습니다",
"data": {
"id": 3,
"type": "LION",
"nickname": "testUser",
"content": "안녕하세요3333",
"time": "2023-09-18 00:11:44"
}
}
"""
)))
@ApiResponse(responseCode = "400", description = "시간 형식을 잘못 입력한 경우",
content = @Content(schema = @Schema(implementation = SuccessApiResponse.class),
examples = @ExampleObject(name = "example",
description = "시간 형식을 잘못 입력한 경우 예시",
value = """
{
"code": 400,
"message": "time 형식을 yyyy-MM-dd HH:mm:ss으로 작성해 주세요",
"data": null
}
"""
)))
@ApiResponse(responseCode = "401", description = "게시글 수정 권한이 없는 경우",
content = @Content(schema = @Schema(implementation = SuccessApiResponse.class),
examples = @ExampleObject(name = "example",
description = "시간 형식을 잘못 입력한 경우 예시",
value = """
{
"code": 401,
"message": "게시글 수정 혹은 삭제 권한이 존재하지 않습니다",
"data": null
}
"""
)))
@ApiResponse_Internal_Server_Error
@PutMapping("/{postId}")
public ResponseEntity<SuccessApiResponse<PostResponse>> update(@PathVariable("postId") Long postId, @RequestBody PostRequest postRequest) {
return ResponseEntity.status(HttpStatus.OK)
.body(SuccessApiResponse.success(SuccessCode.POST_UPDATE_SUCCESS,
postService.update(postId, postRequest)));
}

@Operation(summary = "게시글 삭제", description = "게시글 삭제 API")
@ApiResponse(responseCode = "200", description = """
정상 응답
게시글이 정상적으로 삭제된 경우
""",
content = @Content(schema = @Schema(implementation = SuccessApiResponse.class),
examples = @ExampleObject(name = "example",
description = "정상 응답 예시",
value = """
{
"code": 200,
"message": "게시글 삭제가 정상적으로 처리되었습니다",
"data": null
}
"""
)))
@ApiResponse(responseCode = "400", description = "시간 형식을 잘못 입력한 경우",
content = @Content(schema = @Schema(implementation = SuccessApiResponse.class),
examples = @ExampleObject(name = "example",
description = "시간 형식을 잘못 입력한 경우 예시",
value = """
{
"code": 400,
"message": "time 형식을 yyyy-MM-dd HH:mm:ss으로 작성해 주세요",
"data": null
}
"""
)))
@ApiResponse(responseCode = "401", description = "게시글 삭제 권한이 없는 경우",
content = @Content(schema = @Schema(implementation = SuccessApiResponse.class),
examples = @ExampleObject(name = "example",
description = "시간 형식을 잘못 입력한 경우 예시",
value = """
{
"code": 401,
"message": "게시글 수정 혹은 삭제 권한이 존재하지 않습니다",
"data": null
}
"""
)))
@ApiResponse_Internal_Server_Error
@DeleteMapping("/{postId}")
public ResponseEntity<SuccessApiResponse<?>> delete(@PathVariable("postId") Long postId, @RequestBody PostRequest postRequest) {
int result = postService.delete(postId, postRequest);
if (result == SUCCESS) {
return ResponseEntity.status(HttpStatus.OK)
.body(SuccessApiResponse.success(SuccessCode.POST_DELETE_SUCCESS));
} else {
throw new CustomException(ErrorCode.INTERNAL_SERVER_ERROR);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package org.ai.roboadvisor.domain.community.dto.request;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.ai.roboadvisor.domain.community.entity.Post;

import javax.validation.constraints.NotBlank;
import java.time.LocalDateTime;

@Getter
@NoArgsConstructor
@AllArgsConstructor
public class PostRequest {

@Schema(description = "사용자의 투자 성향", example = "SHEEP")
@NotBlank
private String type;

@Schema(description = "사용자의 닉네임", example = "testUser")
@NotBlank
private String nickname;

@Schema(description = "게시글 내용", example = "안녕하세요. 게시글 1입니다. ")
@NotBlank
private String content;

@Schema(description = "시간", example = "2023-09-18 02:44:33")
@NotBlank
private String time;

public static Post fromPostRequest(PostRequest postRequest, LocalDateTime time) {
return Post.builder()
.type(postRequest.getType())
.nickname(postRequest.getNickname())
.content(postRequest.getContent())
.time(time)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.ai.roboadvisor.domain.community.dto.response;

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.ai.roboadvisor.domain.community.entity.Post;

import java.time.LocalDateTime;

@Getter
@AllArgsConstructor
public class PostResponse {

private Long id;
private String type;
private String nickname;
private String content;

@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "Asia/Seoul")
private LocalDateTime time;

public static PostResponse of(Long id, String type, String nickname, String content, LocalDateTime time) {
return new PostResponse(id, type, nickname, content, time);
}

public static PostResponse fromPostEntity(Post post) {
return new PostResponse(post.getId(), post.getType(), post.getNickname(), post.getContent(), post.getTime());
}
}
57 changes: 57 additions & 0 deletions src/main/java/org/ai/roboadvisor/domain/community/entity/Post.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package org.ai.roboadvisor.domain.community.entity;

import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.time.LocalDateTime;

@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED) // 인자 없는 기본 생성자 필요
@Entity
@Table(name = "posts")
public class Post {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "post_id")
private Long id;

@Column(name = "post_type", nullable = false, length = 10)
private String type;

@Column(name = "post_nickname", nullable = false, length = 50)
private String nickname;

@Column(name = "post_content", nullable = false, columnDefinition = "TEXT")
private String content;

@Column(name = "post_time", nullable = false)
private LocalDateTime time;

@Builder
private Post(String type, String nickname, String content, LocalDateTime time) {
this.type = type;
this.nickname = nickname;
this.content = content;
this.time = time;
}

public void setType(String type) {
this.type = type;
}

public void setNickname(String nickname) {
this.nickname = nickname;
}

public void setContent(String content) {
this.content = content;
}

public void setTime(LocalDateTime time) {
this.time = time;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package org.ai.roboadvisor.domain.community.repository;

import org.ai.roboadvisor.domain.community.entity.Post;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface PostRepository extends JpaRepository<Post, Long> {

Optional<Post> findPostById(Long id);

}
Loading

0 comments on commit 26560c1

Please sign in to comment.