Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: YSL-22 자기소개 저장 및 조회하는 기능 추가 #17

Open
wants to merge 7 commits into
base: develop
Choose a base branch
from
Open
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,12 @@
package org.idiot.yesslave.global.exception;

public class NotFoundException extends RuntimeException {

public NotFoundException() {
super("유효한 데이터가 없습니다.");
}

public NotFoundException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,29 +23,30 @@
@ControllerAdvice
@EnableAutoConfiguration(exclude = ErrorMvcAutoConfiguration.class)
public class RootExceptionHandler {

@ExceptionHandler(Exception.class)
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
@ApiResponse(responseCode = "500", description = "Internal Server Error", content = {
@Content(schema = @Schema(implementation = Problem.class))
@Content(schema = @Schema(implementation = Problem.class))
})
public ResponseEntity<Problem> exceptionHandler(Exception e) {

log.error("[ 500 ERROR ] : ", e);

Problem problem = Problem.builder()
.withStatus(Status.INTERNAL_SERVER_ERROR)
.withTitle(Status.INTERNAL_SERVER_ERROR.getReasonPhrase())
.withDetail(e.getMessage())
.build();
.withStatus(Status.INTERNAL_SERVER_ERROR)
.withTitle(Status.INTERNAL_SERVER_ERROR.getReasonPhrase())
.withDetail(e.getMessage())
.build();

return ResponseEntity
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(problem);
.status(HttpStatus.INTERNAL_SERVER_ERROR)
.body(problem);
}

@ResponseStatus(value = HttpStatus.BAD_REQUEST)
@ApiResponse(responseCode = "400", description = "Bad Request", content = {
@Content(schema = @Schema(implementation = InvalidResponse.class))
@Content(schema = @Schema(implementation = InvalidResponse.class))
})
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Problem> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
Expand All @@ -54,40 +55,60 @@ public ResponseEntity<Problem> methodArgumentNotValidExceptionHandler(MethodArgu
BindingResult bindingResult = e.getBindingResult();

List<InvalidResponse> responses = bindingResult.getFieldErrors().stream()
.map(fieldError -> new InvalidResponse(fieldError.getField()
, fieldError.getDefaultMessage()
, fieldError.getRejectedValue())
).toList();
.map(fieldError -> new InvalidResponse(fieldError.getField()
, fieldError.getDefaultMessage()
, fieldError.getRejectedValue())
).toList();

Problem problem = Problem.builder()
.withStatus(Status.BAD_REQUEST)
.withTitle(Status.BAD_REQUEST.getReasonPhrase())
.with("parameters", responses)
.build();
.withStatus(Status.BAD_REQUEST)
.withTitle(Status.BAD_REQUEST.getReasonPhrase())
.with("parameters", responses)
.build();

return ResponseEntity
.status(HttpStatus.BAD_REQUEST)
.body(problem);
.status(HttpStatus.BAD_REQUEST)
.body(problem);
}

@ResponseStatus(value = HttpStatus.BAD_REQUEST)
@ApiResponse(responseCode = "400", description = "Bad Request", content = {
@Content(schema = @Schema(implementation = InvalidResponse.class))
@Content(schema = @Schema(implementation = InvalidResponse.class))
})
@ExceptionHandler(ConstraintViolationException.class)
public Problem constraintViolationExceptionHandler(ConstraintViolationException e) {
log.error("[ 400 ERROR ] : ", e);

List<InvalidResponse> responses = e.getConstraintViolations().stream()
.map(fieldError -> new InvalidResponse(fieldError.getPropertyPath().toString()
, fieldError.getMessage()
, fieldError.getInvalidValue())
).toList();
.map(fieldError -> new InvalidResponse(fieldError.getPropertyPath().toString()
, fieldError.getMessage()
, fieldError.getInvalidValue())
).toList();

return Problem.builder()
.withStatus(Status.BAD_REQUEST)
.withTitle(Status.BAD_REQUEST.getReasonPhrase())
.with("parameters", responses)
.build();
.withStatus(Status.BAD_REQUEST)
.withTitle(Status.BAD_REQUEST.getReasonPhrase())
.with("parameters", responses)
.build();
}

@ExceptionHandler(NotFoundException.class)
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
@ApiResponse(responseCode = "404", description = "Not Found", content = {
@Content(schema = @Schema(implementation = Problem.class))
})
public ResponseEntity<Problem> notFoundExceptionHandler(Exception e) {

log.error("[ 404 ERROR ] : ", e);

Problem problem = Problem.builder()
.withStatus(Status.NOT_FOUND)
.withTitle(Status.NOT_FOUND.getReasonPhrase())
.withDetail(e.getMessage())
.build();

return ResponseEntity
.status(HttpStatus.NOT_FOUND)
.body(problem);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.idiot.yesslave.introduce.application;

import lombok.RequiredArgsConstructor;
import org.idiot.yesslave.global.exception.NotFoundException;
import org.idiot.yesslave.introduce.domain.Introduce;
import org.idiot.yesslave.introduce.domain.IntroduceResponse;
import org.idiot.yesslave.introduce.domain.IntroduceSaveRequest;
import org.idiot.yesslave.introduce.repository.IntroduceRepository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@RequiredArgsConstructor
public class IntroduceService {

private final IntroduceRepository introduceRepository;

@Transactional
public Long registerIntroduce(IntroduceSaveRequest request) {
return introduceRepository.save(Introduce.registerOf(request))
.getId();
}

@Transactional(readOnly = true)
public IntroduceResponse findIntroduce(Long id) {
Introduce introduce = introduceRepository.findById(id)
.orElseThrow(NotFoundException::new);

return IntroduceResponse.of(introduce);
}
}
87 changes: 87 additions & 0 deletions src/main/java/org/idiot/yesslave/introduce/domain/Introduce.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package org.idiot.yesslave.introduce.domain;

import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.hibernate.annotations.Comment;
import org.idiot.yesslave.global.jpa.AuditInformation;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;

@Entity
@Getter
@AllArgsConstructor
@Table(name = "INTRODUCE")
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Introduce extends AuditInformation {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "INTRODUCE_ID", nullable = false)
private Long id;

@NotNull
@Comment("이름")
@Column(name = "NAME", nullable = false, length = 32)
private String name;

@NotNull
@Comment("이메일")
@Column(name = "EMAIL", nullable = false, length = 64)
private String email;

@Comment("이미지 URL")
@Column(name = "IMAGE_URL", length = 512)
private String imageUrl;

@Comment("자기소개")
@Column(name = "BIO", length = 512)
private String bio;

@Comment("깃헙 URL")
@Column(name = "GITHUB_URL", length = 512)
private String githubUrl;

@Comment("회사명")
@Column(name = "COMPANY", length = 64)
private String company;

@Comment("회사 URL")
@Column(name = "COMPANY_URL", length = 256)
private String companyUrl;

@Comment("블로그 URL")
@Column(name = "SITE_URL", length = 256)
private String siteUrl;

@Comment("SNS URL 1")
@Column(name = "SNS_URL_1", length = 512)
private String snsUrl1;

@Comment("SNS URL 2")
@Column(name = "SNS_URL_2", length = 512)
private String snsUrl2;

public static Introduce registerOf(IntroduceSaveRequest request) {
Introduce introduce = new Introduce();

introduce.name = request.getName();
introduce.email = request.getEmail();
introduce.imageUrl = request.getImageUrl();
introduce.bio = request.getBio();
introduce.githubUrl = request.getGithubUrl();
introduce.company = request.getCompany();
introduce.siteUrl = request.getSiteUrl();
introduce.snsUrl1 = request.getSnsUrl1();
introduce.snsUrl2 = request.getSnsUrl2();

return introduce;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package org.idiot.yesslave.introduce.domain;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@Schema(description = "자기소개 조회 DTO")
public class IntroduceResponse {

@Schema(description = "이름", example = "김갑돌")
private String name;

@Schema(description = "이메일", example = "[email protected]")
private String email;

@Schema(description = "프로필 이미지 URL", example = "http://aa.com")
private String imageUrl;

@Schema(description = "자기소개", example = "안녕하세요. 김갑돌입니다.")
private String bio;

@Schema(description = "Github URL", example = "https://github.com")
private String githubUrl;

@Schema(description = "회사명", example = "(주)치킨이맛있어요")
private String company;

@Schema(description = "회사 URL", example = "https://bbq.co.kr/")
private String companyUrl;

@Schema(description = "블로그 URL", example = "https://section.blog.naver.com/BlogHome.naver")
private String siteUrl;

@Schema(description = "첫번째 SNS URL", example = "https://twitter.com/")
private String snsUrl1;

@Schema(description = "두번째 SNS URL", example = "http://linkedin.com/")
private String snsUrl2;

public static IntroduceResponse of(Introduce introduce) {
IntroduceResponse response = new IntroduceResponse();

response.name = introduce.getName();
response.email = introduce.getEmail();
response.imageUrl = introduce.getImageUrl();
response.bio = introduce.getBio();
response.githubUrl = introduce.getGithubUrl();
response.company = introduce.getCompany();
response.companyUrl = introduce.getCompanyUrl();
response.siteUrl = introduce.getSiteUrl();
response.snsUrl1 = introduce.getSnsUrl1();
response.snsUrl2 = introduce.getSnsUrl2();

return response;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package org.idiot.yesslave.introduce.domain;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;

@Getter
@AllArgsConstructor
@NoArgsConstructor(access = AccessLevel.PRIVATE)
@Schema(description = "자기소개 생성을 위한 요청 DTO")
public class IntroduceSaveRequest {

@NotBlank(message = "이름을 입력해주세요.")
@Size(max = 32, message = "이름은 32자 미만으로 작성해주세요.")
@Schema(description = "이름", example = "김갑돌")
private String name;

//TODO: 이메일 유효성도 체크 필요
@NotBlank(message = "이메일을 입력해주세요.")
@Size(max = 64, message = "이메일은 64자 미만으로 작성해주세요.")
@Schema(description = "이메일", example = "[email protected]")
private String email;

@Size(max = 512, message = "이미지 URL은 512자 미만으로 작성해주세요.")
@Schema(description = "프로필 이미지 URL", example = "http://aa.com")
private String imageUrl;

@Size(max = 512, message = "자기소개는 512자 미만으로 작성해주세요.")
@Schema(description = "자기소개", example = "안녕하세요. 김갑돌입니다.")
private String bio;

@Size(max = 512, message = "Github URL은 512자 미만으로 작성해주세요.")
@Schema(description = "Github URL", example = "https://github.com")
private String githubUrl;

@Size(max = 64, message = "회사명은 64자 미만으로 작성해주세요.")
@Schema(description = "회사명", example = "(주)치킨이맛있어요")
private String company;

@Size(max = 256, message = "회사 URL은 64자 미만으로 작성해주세요.")
@Schema(description = "회사 URL", example = "https://bbq.co.kr/")
private String companyUrl;

@Size(max = 256, message = "블로그 URL은 64자 미만으로 작성해주세요.")
@Schema(description = "블로그 URL", example = "https://section.blog.naver.com/BlogHome.naver")
private String siteUrl;

@Size(max = 512, message = "SNS URL 1은 64자 미만으로 작성해주세요.")
@Schema(description = "첫번째 SNS URL", example = "https://twitter.com/")
private String snsUrl1;

@Size(max = 512, message = "SNS URL 2은 64자 미만으로 작성해주세요.")
@Schema(description = "두번째 SNS URL", example = "http://linkedin.com/")
private String snsUrl2;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package org.idiot.yesslave.introduce.repository;

import org.idiot.yesslave.introduce.domain.Introduce;
import org.springframework.data.jpa.repository.JpaRepository;

public interface IntroduceRepository extends JpaRepository<Introduce, Long> {
}
Loading