Skip to content

[이승민] Sprint7#239

Open
chosi123 wants to merge 193 commits into
codeit-bootcamp-spring:이승민from
chosi123:sprint7
Open

[이승민] Sprint7#239
chosi123 wants to merge 193 commits into
codeit-bootcamp-spring:이승민from
chosi123:sprint7

Conversation

@chosi123
Copy link
Copy Markdown
Collaborator

@chosi123 chosi123 commented Mar 31, 2026

요구사항

프로파일 기반 설정 관리

  • 개발, 운영 환경에 대한 프로파일을 구성하세요.
  • application-dev.yaml, application-prod.yaml 파일을 생성하세요.
  • 다음과 같은 설정값을 프로파일별로 분리하세요.
  • 데이터베이스 연결 정보 설정
  • 서버 포트 설정

로그 관리

  • Lombok의 @slf4j 어노테이션을 활용해 로깅을 쉽게 추가할 수 있도록 구성하세요.
  • application.yaml에 기본 로깅 레벨을 설정하세요. (기본적으로 info 레벨로 설정)
  • 환경 별 적절한 로깅 레벨을 프로파일 별로 설정해보세요.
  • SQL 로그를 보기 위해 설정했던 레벨은 유지합니다.
  • 개발 환경에서 우리 프로젝트의 로그는 debug 레벨로 설정합니다.
  • 운영 환경에서 우리 프로젝트의 로그는 info 레벨로 설정합니다.
  • Spring Boot의 기본 로깅 구현체인 Logback의 설정 파일을 구성하세요.
  • logback-spring.xml 파일을 생성하세요.
  • 로그 메시지 출력 패턴과 방식을 커스터마이징하세요. ({년}-{월}-{일} {시}:{분}:{초}:{밀리초} [{스레드명}] {로그 레벨(5글자)} {로거 이름(최대 36글자)} - {로그 메시지})
  • 콘솔과 파일에 동시에 로그를 기록하도록 설정하세요.
  • 로그 파일은 {프로젝트 루트}/.logs 경로에 저장되도록 설정하세요.
  • 로그 파일은 일자별로 롤링되도록 구성하세요.
  • 로그 파일은 30일간 보관하도록 구성하세요.
  • 서비스 레이어와 컨트롤러 레이어의 주요 메소드에 로깅을 추가하세요.
  • 로깅 레벨을 적절히 사용하세요: ERROR, WARN, INFO, DEBUG
  • 사용자 생성/수정/삭제 메소드에 로깅을 추가하세요.
  • 채널 생성/수정/삭제 메소드에 로깅을 추가하세요.
  • 메시지 생성/수정/삭제 메소드에 로깅을 추가하세요.
  • 파일 업로드/다운로드 메소드에 로깅을 추가하세요.

예외 처리 고도화

  • 커스텀 예외를 설계하고 구현하세요. (패키지: com.sprint.mission.discodeit.exception[.{도메인}])
  • ErrorCode Enum 클래스를 통해 예외 코드명과 메시지를 정의하세요.
  • 모든 예외의 기본이 되는 DiscodeitException 클래스를 정의하세요. (details 속성 포함)
  • DiscodeitException을 상속하는 주요 도메인 별 메인 예외 클래스를 정의하세요. (UserException, ChannelException 등)
  • 도메인 메인 예외 클래스를 상속하는 구체적인 예외 클래스를 정의하세요. (UserNotFoundException, UserAlreadyExistException 등)
  • 기존에 구현했던 표준 예외(NoSuchElementException, IllegalArgumentException 등)를 커스텀 예외로 대체하세요.
  • ErrorResponse를 통해 일관된 예외 응답을 정의하세요. (status, exceptionType 포함)
  • ErrorResponse와 @RestControllerAdvice를 활용해 예외를 처리하는 예외 핸들러를 구현하세요.

유효성 검사

  • Spring Validation 의존성을 추가하세요.
  • 주요 Request DTO에 제약 조건 어노테이션(@NotNull, @notblank, @SiZe, @Email 등)을 추가하세요.
  • 컨트롤러에 @Valid를 사용해 요청 데이터를 검증하세요.
  • 검증 실패 시 발생하는 MethodArgumentNotValidException을 전역 예외 핸들러에서 처리하세요.
  • 유효성 검증 실패 시 상세한 오류 메시지를 포함한 응답을 반환하세요.

Actuator

  • Spring Boot Actuator 의존성을 추가하세요.
  • 기본 Actuator 엔드포인트(health, info, metrics, loggers)를 설정하세요.
  • Actuator info를 위한 애플리케이션 정보(이름: Discodeit, 버전: 1.7.0, 자바: 17, 스프링 부트: 3.4.0)를 추가하세요.
  • 주요 설정 정보(데이터소스, JPA, Storage, Multipart 등)를 info에 추가하세요.
  • 서버 실행 후 /actuator/info, /actuator/metrics, /actuator/health, /actuator/loggers를 확인해보세요.

단위 테스트

  • 서비스 레이어의 주요 메소드에 대한 단위 테스트를 작성하세요.
  • UserService: create, update, delete 메소드에 대해 성공/실패 테스트를 각 2개 이상 작성하세요.
  • ChannelService: create(PUBLIC, PRIVATE), update, delete, findByUserId 메소드에 대해 성공/실패 테스트를 각 2개 이상 작성하세요.
  • MessageService: create, update, delete, findByChannelId 메소드에 대해 성공/실패 테스트를 각 2개 이상 작성하세요.
  • Mockito를 활용해 Repository 의존성을 모의(mock)하세요.
  • BDDMockito를 활용해 테스트 가독성을 높이세요.

슬라이스 테스트

  • 레포지토리 레이어의 슬라이스 테스트를 작성하세요. (@DataJpaTest 활용)
  • 테스트 환경을 위한 application-test.yaml을 생성하세요. (H2 인메모리, PostgreSQL 호환 모드)
  • 테스트 실행 시 test 프로파일을 활성화하고 @EnableJpaAuditing을 추가하세요.
  • 주요 레포지토리(User, Channel, Message)의 커스텀 쿼리 및 페이징/정렬 메소드 성공/실패 테스트를 작성하세요.
  • 컨트롤러 레이어의 슬라이스 테스트를 작성하세요. (@WebMvcTest 활용)
  • 필요한 경우 @import를 활용해 관련 Bean을 추가하세요.
  • 주요 컨트롤러(User, Channel, Message)에 대해 성공/실패 테스트를 각 2개 이상 작성하세요.
  • MockMvc를 활용하고 서비스 레이어를 모의(mock)하여 컨트롤러 로직만 테스트하세요.
  • JSON 응답을 검증하는 테스트를 포함하세요.

통합 테스트

  • @SpringBootTest를 활용해 통합 테스트 환경을 구성하세요.
  • H2 인메모리 데이터베이스와 테스트용 프로파일을 활용하세요.
  • 사용자/채널/메시지 관련 주요 API 엔드포인트에 대해 성공/실패 테스트를 각 2개 이상 작성하세요.
  • 각 테스트는 @transactional을 활용해 독립적으로 실행하세요.

주요 변경사항

스크린샷

image

멘토에게

  • 병합 문제가 또다시 발생하여 추후 수정하겠습니다.

chosi123 and others added 30 commits March 6, 2026 18:41
refactor: UserService에 커스텀 예외 처리 적용, 로깅 추가
# Conflicts:
#	build.gradle
#	src/main/java/com/sprint/mission/discodeit/DiscodeitApplication.java
#	src/main/java/com/sprint/mission/discodeit/controller/AuthController.java
#	src/main/java/com/sprint/mission/discodeit/controller/BinaryContentController.java
#	src/main/java/com/sprint/mission/discodeit/controller/ChannelController.java
#	src/main/java/com/sprint/mission/discodeit/controller/MessageController.java
#	src/main/java/com/sprint/mission/discodeit/controller/ReadStatusController.java
#	src/main/java/com/sprint/mission/discodeit/controller/UserController.java
#	src/main/java/com/sprint/mission/discodeit/dto/binarycontent/BinaryContentResponseDto.java
#	src/main/java/com/sprint/mission/discodeit/dto/channel/ChannelResponseDto.java
#	src/main/java/com/sprint/mission/discodeit/dto/channel/PrivateChannelCreateRequestDto.java
#	src/main/java/com/sprint/mission/discodeit/dto/channel/PublicChannelCreateRequestDto.java
#	src/main/java/com/sprint/mission/discodeit/dto/message/MessageCreateRequestDto.java
#	src/main/java/com/sprint/mission/discodeit/dto/message/MessageResponseDto.java
#	src/main/java/com/sprint/mission/discodeit/dto/readstatus/ReadStatusCreateRequestDto.java
#	src/main/java/com/sprint/mission/discodeit/dto/readstatus/ReadStatusResponseDto.java
#	src/main/java/com/sprint/mission/discodeit/dto/user/UserCreateRequestDto.java
#	src/main/java/com/sprint/mission/discodeit/dto/user/UserResponseDto.java
#	src/main/java/com/sprint/mission/discodeit/dto/user/UserUpdateRequestDto.java
#	src/main/java/com/sprint/mission/discodeit/dto/userstatus/UserStatusCreateRequestDto.java
#	src/main/java/com/sprint/mission/discodeit/dto/userstatus/UserStatusResponseDto.java
#	src/main/java/com/sprint/mission/discodeit/entity/BinaryContent.java
#	src/main/java/com/sprint/mission/discodeit/entity/Channel.java
#	src/main/java/com/sprint/mission/discodeit/entity/Message.java
#	src/main/java/com/sprint/mission/discodeit/entity/ReadStatus.java
#	src/main/java/com/sprint/mission/discodeit/entity/User.java
#	src/main/java/com/sprint/mission/discodeit/entity/UserStatus.java
#	src/main/java/com/sprint/mission/discodeit/exception/GlobalExceptionHandler.java
#	src/main/java/com/sprint/mission/discodeit/mapper/binarycontent/BinaryContentResponseMapper.java
#	src/main/java/com/sprint/mission/discodeit/mapper/channel/ChannelResponseMapper.java
#	src/main/java/com/sprint/mission/discodeit/mapper/message/MessageResponseMapper.java
#	src/main/java/com/sprint/mission/discodeit/mapper/readstatus/ReadStatusResponseMapper.java
#	src/main/java/com/sprint/mission/discodeit/mapper/user/UserResponseMapper.java
#	src/main/java/com/sprint/mission/discodeit/mapper/userstatus/UserStatusResponseMapper.java
#	src/main/java/com/sprint/mission/discodeit/repository/BinaryContentRepository.java
#	src/main/java/com/sprint/mission/discodeit/repository/ChannelRepository.java
#	src/main/java/com/sprint/mission/discodeit/repository/MessageRepository.java
#	src/main/java/com/sprint/mission/discodeit/repository/ReadStatusRepository.java
#	src/main/java/com/sprint/mission/discodeit/repository/UserRepository.java
#	src/main/java/com/sprint/mission/discodeit/repository/UserStatusRepository.java
#	src/main/java/com/sprint/mission/discodeit/service/AuthService.java
#	src/main/java/com/sprint/mission/discodeit/service/BinaryContentService.java
#	src/main/java/com/sprint/mission/discodeit/service/ChannelService.java
#	src/main/java/com/sprint/mission/discodeit/service/MessageService.java
#	src/main/java/com/sprint/mission/discodeit/service/ReadStatusService.java
#	src/main/java/com/sprint/mission/discodeit/service/UserService.java
#	src/main/java/com/sprint/mission/discodeit/service/basic/BasicAuthService.java
#	src/main/java/com/sprint/mission/discodeit/service/basic/BasicBinaryContentService.java
#	src/main/java/com/sprint/mission/discodeit/service/basic/BasicChannelService.java
#	src/main/java/com/sprint/mission/discodeit/service/basic/BasicMessageService.java
#	src/main/java/com/sprint/mission/discodeit/service/basic/BasicReadStatusService.java
#	src/main/java/com/sprint/mission/discodeit/service/basic/BasicUserService.java
#	src/main/java/com/sprint/mission/discodeit/service/basic/BasicUserStatusService.java
#	src/main/resources/application.yml
#	src/main/resources/templates/index.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant