Skip to content

Commit

Permalink
[FE] 질문 작정 페이지에 필요한 질문 목 데이터 및 카드의 상태 처리 (#263)
Browse files Browse the repository at this point in the history
* [BE] fix: CD 스크립트 수정 (#246)

* fix: CD 스크립트 수정

* chore: 저장 데이터 dev에서 활용할 수 있도록 수정

* [FE] refactor: LandingPage 경로 변경 (#249)

* refactor: LandingPage의 경로 변경

* refactor: App 에서 사이드바 주석 처리

* refactor: QuestionCard, ReviewWritingCard 폴더 위치 변경

- ReviewWritingFormPage의 components로 이동

* refactor: CheckboxItem props 타입 변경

Co-Authored-By: ImxYJL <[email protected]>
Co-Authored-By: soosoo22 <[email protected]>
Co-Authored-By: Fe <[email protected]>

* refactor: ReviewWritingFormPage 페이지 경로 변경

Co-Authored-By: ImxYJL <[email protected]>
Co-Authored-By: soosoo22 <[email protected]>
Co-Authored-By: Fe <[email protected]>

* feat: 리뷰 카드 질문 상수 생성 및 객관식 체크 박스 선택 해제 기능 추가

Co-Authored-By: ImxYJL <[email protected]>
Co-Authored-By: soosoo22 <[email protected]>
Co-Authored-By: Fe <[email protected]>

* feat: 객관식 최대 최소 선택 개수 기능 추가

- 최대 개수 선택 후 추가 선택을 시도하면 최대 개수 안내 문구 출력

Co-Authored-By: ImxYJL <[email protected]>
Co-Authored-By: soosoo22 <[email protected]>
Co-Authored-By: Fe <[email protected]>

* feat: 이전 버튼 비활성화

Co-Authored-By: ImxYJL <[email protected]>
Co-Authored-By: soosoo22 <[email protected]>
Co-Authored-By: Fe <[email protected]>

* feat: 리뷰 카드의 답변이 유효할 때 다음 버튼 활성화 기능가

Co-Authored-By: ImxYJL <[email protected]>
Co-Authored-By: soosoo22 <[email protected]>
Co-Authored-By: Fe <[email protected]>

* [BE] Swagger API 문서 업데이트 (#254)

* docs: 리뷰 api 문서를 위한 swagger 어노테이션 추가

* refactor: 사용하지 않는 dto 삭제

* docs: api 문서에 최소 및 최대 설정 안내 추가

* docs: 리뷰 그룹 api를 위한 swagger 어노테이션 추가

* refactor: Spring에서 제공하는 APPLICATION_JSON_VALUE 사용

* [BE] feat: 예외에 대한 로그 작성 (#255)

* feat: Controller advice 에 로깅 추가

* refactor: 스택 트레이스 로깅 추가

* feat: 리뷰그룹 생성시 길이 검증 로깅 추가

* feat: 답변 길이 검증 로깅 추가

* feat: 리뷰 그룹 코드 검증 검증 로깅 추가

* feat: 리뷰 조회 검증 검증 로깅 추가

* feat: 선택된 키워드 존재하지 않는 검증 로깅 추가

* feat: 중복 선택된 키워드 검증 로깅 추가

* feat: 키워드 조회 검증 로깅 추가

* feat: 선택 키워드 갯수 검증 로깅 추가

* feat: 선택된 질문 중복 검증 로깅 추가

* feat: 질문 조회 검증 로깅 추가

* feat: 중복 질문 검증 로깅 추가

* feat: 스프링 발생 예외 로깅에 메세지 추가

* feat: 인코딩 설정

* style: 개행 수정

Co-authored-by: Donghoon Lee <[email protected]>

* style: 개행 및 공백 수정

* refactor: 불필요한 검증 제거

- 선택된 키워드와 질문이 DB에 있는지를 validator 에서 검증한 후에도, repository.getById 를 할 때 한번 더 검증이 들어간다. 따라서 'DB에 있는지'에 대한 검증을 validator 에서 할 필요는 없다는 판단 하에 해당 로직을 삭제한다.

---------

Co-authored-by: Donghoon Lee <[email protected]>

* feat: openning 질문에서 선택한 꼬리 질문 카테고리 질문 카드로 넘어가는 기능 추가

* design: 리뷰 작성 페이지 카드 스타일 변경

* [FE] refactor:  Textarea를 사용하는 공통 장문형 답변 입력 컴포넌트 분리 (#252)

* feat: 공통 textarea 컴포넌트 작성

* refactor: longReviewItem의 로직을 커스텀 훅으로 분리

* refactor: longReviewItem으로 이름 변경 및 컴포넌트 구현

* chore: 기존의 ReviewItem 제거 및 리뷰 작성 페이지에 LongReviewItem 적용

* [FE] refactor: 공용 모달 훅 추가 및 LongReviewItem 리팩토링 (#258)

* feat: 모달 상태 관리 훅 추가

* refactor: LongReviewItem 컴포넌트가 외부의 event를 props로 받을 수 있도록 변경

* docs: ESSAY 의 가이드 라인에 리뷰이 추가

* design: QuestionCard 폰트 사이즈 변경

* feat: 리뷰 작성 카드에서 꼬리 질문 객관식 및 서술형 기능 추가

* feat : 서술형 질문에 대한 답변 기능 및 다음 단계 진행 기능 추가

* fix: isValidatedAnswer 에서 currentQuestions 없는 경우에 대한 오류 처리

* fix:  다음,제출 버튼의 styledType 수정

* fix: 리뷰 작성 카드 currentIndex=0 일 때 다음 클릭 시 다음 카드로 넘어가지 않는 오류 수정

* refactor: 스타일 props 접두사에 달러 표시 추가

* chore: 오타 수정

---------

Co-authored-by: Donghoon Lee <[email protected]>
Co-authored-by: ImxYJL <[email protected]>
Co-authored-by: soosoo22 <[email protected]>
Co-authored-by: Fe <[email protected]>
Co-authored-by: Kimprodp <[email protected]>
Co-authored-by: Yeongseo Na <[email protected]>
  • Loading branch information
7 people authored Aug 8, 2024
1 parent 03b2a22 commit 5093449
Show file tree
Hide file tree
Showing 65 changed files with 935 additions and 340 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/backend-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ on:
env:
ARTIFACT_NAME: review-me-dev
ARTIFACT_DIRECTORY: ./backend/build/libs
APPLICATION_DIRECTORY: ~/review-me-app

jobs:
build:
Expand Down Expand Up @@ -66,6 +67,10 @@ jobs:
with:
name: ${{ env.ARTIFACT_NAME }}

- name: Copy application related files to other directory
run: |
sudo mv * ${{ env.APPLICATION_DIRECTORY }}
- name: Find ${{ env.ARTIFACT_NAME }} process
run: |
echo "Checking processes..."
Expand All @@ -90,4 +95,5 @@ jobs:
- name: Start server
run: |
cd ${{ env.APPLICATION_DIRECTORY }}
sudo nohup java -jar ${{ env.ARTIFACT_NAME }}.jar --server.port=80 --spring.config.location=application-dev.yml &
2 changes: 1 addition & 1 deletion backend/src/main/java/reviewme/DatabaseInitializer.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import reviewme.question.domain.Question;
import reviewme.review.repository.QuestionRepository;

@Profile("local")
@Profile({"local", "dev"})
@Component
@RequiredArgsConstructor
public class DatabaseInitializer {
Expand Down
35 changes: 30 additions & 5 deletions backend/src/main/java/reviewme/global/GlobalExceptionHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ProblemDetail;
Expand All @@ -24,52 +23,59 @@
import reviewme.global.exception.BadRequestException;
import reviewme.global.exception.FieldErrorResponse;
import reviewme.global.exception.NotFoundException;
import reviewme.global.exception.ReviewMeException;
import reviewme.global.exception.UnAuthorizedException;

@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

@ExceptionHandler(NotFoundException.class)
public ProblemDetail handleNotFoundException(NotFoundException ex) {
logReviewMeException(ex);
return ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, ex.getErrorMessage());
}

@ExceptionHandler(BadRequestException.class)
public ProblemDetail handleBadRequestException(BadRequestException ex) {
logReviewMeException(ex);
return ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, ex.getErrorMessage());
}

@ExceptionHandler(UnAuthorizedException.class)
public ProblemDetail handleUnAuthorizedException(UnAuthorizedException ex) {
logReviewMeException(ex);
return ProblemDetail.forStatusAndDetail(HttpStatus.UNAUTHORIZED, ex.getErrorMessage());
}

@ExceptionHandler(Exception.class)
public ProblemDetail handleException(Exception ex) {
log.error("An error occurred", ex);
logInitialServerError(ex);
return ProblemDetail.forStatusAndDetail(HttpStatus.INTERNAL_SERVER_ERROR, "서버 에러가 발생했습니다.");
}

// Following exceptions are exceptions that occur in Spring
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public ProblemDetail handleHttpRequestMethodNotSupportedException(Exception ex) {
logSpringException(ex);
return ProblemDetail.forStatusAndDetail(HttpStatus.METHOD_NOT_ALLOWED, "지원하지 않는 HTTP 메서드입니다.");
}

@ExceptionHandler(HttpMediaTypeException.class)
public ProblemDetail handleHttpMediaTypeException(Exception ex) {
logSpringException(ex);
return ProblemDetail.forStatusAndDetail(HttpStatus.UNSUPPORTED_MEDIA_TYPE, "잘못된 media type 입니다.");
}

@ExceptionHandler({MissingRequestValueException.class, MissingServletRequestPartException.class})
public ProblemDetail handleMissingRequestException(Exception ex) {
logSpringException(ex);
return ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, "필수 요청 데이터가 누락되었습니다.");
}

@ExceptionHandler({ServletRequestBindingException.class, HttpMessageNotReadableException.class})
public ProblemDetail handleServletRequestBindingException(Exception ex) {
logSpringException(ex);
return ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, "요청을 읽을 수 없습니다.");
}

Expand All @@ -78,16 +84,19 @@ public ProblemDetail handleServletRequestBindingException(Exception ex) {
TypeMismatchException.class, HandlerMethodValidationException.class
})
public ProblemDetail handleRequestFormatException(Exception ex) {
logSpringException(ex);
return ProblemDetail.forStatusAndDetail(HttpStatus.BAD_REQUEST, "요청의 형식이 잘못되었습니다.");
}

@ExceptionHandler({NoHandlerFoundException.class, NoResourceFoundException.class})
public ProblemDetail handleNoHandlerFoundException(Exception ex) {
logSpringException(ex);
return ProblemDetail.forStatusAndDetail(HttpStatus.NOT_FOUND, "잘못된 경로의 요청입니다.");
}

@ExceptionHandler(MethodArgumentNotValidException.class)
public ProblemDetail handleMethodArgumentNotValid(MethodArgumentNotValidException ex) {
logSpringException(ex);
List<FieldErrorResponse> fieldErrors = ex.getBindingResult()
.getFieldErrors()
.stream()
Expand All @@ -104,4 +113,20 @@ public ProblemDetail handleMethodArgumentNotValid(MethodArgumentNotValidExceptio
problemDetail.setProperties(properties);
return problemDetail;
}

private void logReviewMeException(ReviewMeException ex) {
log.info("{} is occurred - {}",
ex.getClass().getSuperclass().getSimpleName(),
ex.getClass().getSimpleName(),
ex
);
}

private void logInitialServerError(Exception ex) {
log.error("Initial server error is occurred", ex);
}

private void logSpringException(Exception ex) {
log.info("Spring error is occurred - {}: {}", ex.getClass().getSimpleName(), ex.getLocalizedMessage());
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package reviewme.keyword.domain.exception;

import java.util.List;
import lombok.extern.slf4j.Slf4j;
import reviewme.global.exception.BadRequestException;

@Slf4j
public class DuplicateKeywordException extends BadRequestException {

public DuplicateKeywordException() {
public DuplicateKeywordException(List<Long> selectedKeywordIds) {
super("키워드는 중복되지 않게 선택해 주세요.");
log.info("Selected keywords are duplicated - selectedKeywordIds: {}", selectedKeywordIds);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package reviewme.keyword.domain.exception;

import lombok.extern.slf4j.Slf4j;
import reviewme.global.exception.BadRequestException;

@Slf4j
public class KeywordLimitExceedException extends BadRequestException {

public KeywordLimitExceedException(int minSize, int maxSize) {
super("키워드는 최소 %d개, 최대 %d개 선택할 수 있어요.".formatted(minSize, maxSize));
log.info("Selected keywords are out of bound - minSize:{}, maxSize: {}", minSize, maxSize);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package reviewme.keyword.domain.exception;

import lombok.extern.slf4j.Slf4j;
import reviewme.global.exception.NotFoundException;

@Slf4j
public class KeywordNotFoundException extends NotFoundException {

public KeywordNotFoundException() {
public KeywordNotFoundException(long id) {
super("키워드가 존재하지 않아요.");
log.info("Keyword not found by id - id: {}", id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,6 @@
public interface KeywordRepository extends JpaRepository<Keyword, Long> {

default Keyword getKeywordById(long id) {
return findById(id).orElseThrow(KeywordNotFoundException::new);
return findById(id).orElseThrow(() -> new KeywordNotFoundException(id));
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
package reviewme.question.domain.exception;

import java.util.List;
import lombok.extern.slf4j.Slf4j;
import reviewme.global.exception.BadRequestException;

@Slf4j
public class DuplicateQuestionException extends BadRequestException {

public DuplicateQuestionException() {
public DuplicateQuestionException(List<Long> selectedQuestionIds) {
super("질문은 중복될 수 없어요.");
log.info("Selected questions are duplicated - selectedQuestionIds: {}", selectedQuestionIds);
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package reviewme.question.domain.exception;

import lombok.extern.slf4j.Slf4j;
import reviewme.global.exception.NotFoundException;

@Slf4j
public class QuestionNotFoundException extends NotFoundException {

public QuestionNotFoundException() {
public QuestionNotFoundException(long questionId) {
super("질문이 존재하지 않아요.");
log.info("Question not found - questionId: {}", questionId);
}
}
Loading

0 comments on commit 5093449

Please sign in to comment.