Skip to content

[윤금비] sprint5#107

Open
geumbi1 wants to merge 11 commits intocodeit-bootcamp-spring:mainfrom
geumbi1:ygb
Open

[윤금비] sprint5#107
geumbi1 wants to merge 11 commits intocodeit-bootcamp-spring:mainfrom
geumbi1:ygb

Conversation

@geumbi1
Copy link
Copy Markdown
Collaborator

@geumbi1 geumbi1 commented Mar 1, 2026

요구사항

기본

  • [o] 기본 항목 1
  • [△] 기본 항목 2

심화

  • [ x] 심화 항목 1
  • [ x] 심화 항목 2

주요 변경사항

멘토에게

  • swagger에서 channel은 생성이 되는데 user는 등록이 계속 안 됩니다(Content-Type 'application/octet-stream' is not supported)어느 부분이 문제인지 알려주시면 감사하겠습니다.
  • 강사님 허락 받고 승현님 코드와 똑같이 되어있습니다.

@geumbi1 geumbi1 added the 미완성🛠️ 스프린트 미션 제출일이지만 미완성했습니다. 죄송합니다. label Mar 1, 2026
Copy link
Copy Markdown

@joonfluence joonfluence left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

총평

전반적으로 계층 구조와 Swagger 문서화가 잘 설계되어 있으나, 런타임에 치명적 영향을 주는 버그가 발견되어 수정이 필요합니다.

P1. file-data-map/*.ser, out/ 디렉토리가 Git에 커밋됨
직렬화된 .ser 파일(수십 개)과 빌드 산출물(out/)이 Git에 포함되어 있습니다. .gitignore에 추가하고 git rm --cached로 tracking을 제거해 주세요. discodeit.iml IDE 파일도 마찬가지입니다.

P4. UserResponse.java 패키지 위치
UserResponsedto.request 패키지에 위치해 있습니다. 응답 DTO이므로 dto.response 패키지로 이동을 권장합니다.

P5. 주석 처리된 코드 정리
ChannelController 등에 주석 처리된 코드 블록이 남아 있습니다. 불필요한 코드는 삭제하고, 필요시 Git 히스토리에서 복구하는 것을 권장합니다.

@Override
public void deleteByUserId(UUID userId) {
this.findByUserId(userId)
.ifPresent(userStatus -> this.deleteByUserId(userStatus.getId()));
Copy link
Copy Markdown

@joonfluence joonfluence Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1. 무한 재귀 — StackOverflowError 발생

deleteByUserId() 내부에서 this.deleteById()를 호출해야 하는데 this.deleteByUserId()를 재귀 호출하고 있습니다.
이 메서드가 호출되면 무조건 StackOverflowError가 발생합니다.

Suggested change
.ifPresent(userStatus -> this.deleteByUserId(userStatus.getId()));
.ifPresent(userStatus -> this.deleteById(userStatus.getId()));

BinaryContent binaryContentNullable = null;
Path path = resolvePath(id);
ReentrantLock lock = fileLockProvider.getLock(path);
lock.lock();
Copy link
Copy Markdown

@joonfluence joonfluence Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1. 데드락 위험 — 파일 미존재 시 lock 미해제

lock.lock() 이후 Files.exists(path) 조건이 false일 때 lock.unlock()이 호출되지 않습니다.
이 패턴이 모든 File*Repository(FileChannelRepository, FileMessageRepository, FileReadStatusRepository, FileUserRepository, FileUserStatusRepository)의 findById() 메서드에 동일하게 존재합니다.

try-finallyif 블록 바깥으로 이동해야 합니다:

lock.lock();
try {
    if (Files.exists(path)) {
        // read logic
    }
} finally {
    lock.unlock();
}

.orElseThrow(
() -> new NoSuchElementException("User with username " + username + " not found"));

if (!user.getPassword().equals(password)) {
Copy link
Copy Markdown

@joonfluence joonfluence Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2. 비밀번호 평문 비교 및 API 노출

비밀번호를 평문으로 비교하고 있으며, login() 반환값인 User 엔티티가 LoginController에서 그대로 API 응답으로 반환되어 비밀번호가 클라이언트에 노출됩니다.

최소한:

  1. 응답은 UserResponse DTO로 변환해서 반환
  2. 향후 PasswordEncoder 도입을 권장합니다.


String newUsername = userUpdateRequest.newUsername();
String newEmail = userUpdateRequest.newEmail();
if (userRepository.existsByEmail(newEmail)) {
Copy link
Copy Markdown

@joonfluence joonfluence Mar 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2. update() 유니크 체크에서 자기 자신 미제외

email/username 중복 체크가 현재 사용자를 제외하지 않습니다. email이나 username을 변경하지 않고 다른 필드만 수정하려 해도 중복 오류가 발생합니다.

// 예시: 자기 자신 제외
if (!user.getEmail().equals(newEmail) && userRepository.existsByEmail(newEmail)) {
    throw new IllegalArgumentException("User with email " + newEmail + " already exists");
}

}

@ExceptionHandler(Exception.class)
public ResponseEntity<String> handlerException(Exception e) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P3] Exception catch-all이 400 BAD_REQUEST 반환

예상치 못한 서버 예외(NPE, DB 오류 등)까지 400으로 반환하면 클라이언트가 원인을 오해할 수 있습니다.

Suggested change
public ResponseEntity<String> handlerException(Exception e) {
public ResponseEntity<String> handlerException(Exception e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(e.getMessage());


@Override
@PatchMapping("/{userId}/userStatus")
public ResponseEntity<UserStatus> StatusUpdateByUserId(
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P4] 메서드/파라미터 네이밍 컨벤션 위반

메서드명 StatusUpdateByUserId가 대문자로 시작하며, 파라미터 Request도 대문자입니다.
Java 컨벤션에 따라 statusUpdateByUserId, request로 변경을 권장합니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

미완성🛠️ 스프린트 미션 제출일이지만 미완성했습니다. 죄송합니다.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants