Skip to content

feat/#47: 코디북 및 코디 CRUD 기능 구현#48

Merged
seokminseok merged 3 commits into
developfrom
feat/#47
Jun 1, 2026
Merged

feat/#47: 코디북 및 코디 CRUD 기능 구현#48
seokminseok merged 3 commits into
developfrom
feat/#47

Conversation

@seokminseok

Copy link
Copy Markdown
Collaborator

📌 관련 이슈

관련된 이슈 번호를 작성해 주세요.

Closes #47


🛠️ 작업 내용

구현한 내용을 간략히 설명해 주세요.

✅ 변경 사항

  • [ ]
  • [ ]

🔍 테스트 내용

테스트한 방법과 결과를 작성해 주세요.

  • 단위 테스트 작성 / 확인
  • 기능 동작 확인

📷 스크린샷 (선택사항)

UI 변경이 있는 경우 첨부해 주세요.

💬 리뷰어에게

리뷰 시 특별히 봐줬으면 하는 부분이 있다면 작성해 주세요.


📋 PR 체크리스트

  • develop 브랜치를 base로 설정했나요?
  • 코드 컨벤션을 준수했나요?
  • 불필요한 주석 / 디버그 코드를 제거했나요?
  • 관련 이슈 번호를 연결했나요?

@seokminseok seokminseok linked an issue Jun 1, 2026 that may be closed by this pull request
@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown

⚠️ Claude 리뷰 생성 중 문제가 발생했습니다. Actions 로그를 확인해 주세요.

@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown

Test Results

1 tests  ±0   1 ✅ ±0   0s ⏱️ ±0s
1 suites ±0   0 💤 ±0 
1 files   ±0   0 ❌ ±0 

Results for commit ec33924. ± Comparison against base commit f3d7104.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown

✅ 테스트 결과: 모든 테스트 통과

항목
전체 1
통과 1
실패 0
건너뜀 0

@jychoi0831 jychoi0831 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

현재 head commit 58b22cc 기준으로 확인했습니다.

P1: /api/v1/**를 공개 경로로 열어 인증 API 전체가 우회됩니다

src/main/java/com/closetnangam/be/global/config/SecurityConfig.java:35부터 PUBLIC_URLS/api/v1/**가 추가되어 있고, SecurityConfig.java:50에서 이 목록을 모두 permitAll()로 처리합니다. 이 패턴은 새 코디북 API만이 아니라 /api/v1 아래의 옷장, 옷, 이미지, 구매 캡처 등 기존 인증 API 전체를 JWT 없이 컨트롤러까지 통과시킵니다.

영향:

인증되지 않은 요청도 Spring Security에서 먼저 차단되지 않습니다. 이번 PR의 OutfitController.java:31부터 OutfitController.java:60처럼 컨트롤러 내부에서 SecurityUtils.getCurrentUserId()를 호출하는 엔드포인트는 토큰이 없을 때 IllegalStateException("인증 정보를 찾을 수 없습니다.")로 실패해 401/403 대신 서버 예외 흐름이 됩니다. 더 큰 문제는 기존 /api/v1 엔드포인트 중 컨트롤러에서 별도 소유권 검증을 빠뜨린 경로가 있으면 그대로 공개 API가 되어 사용자 데이터 접근/변경으로 이어질 수 있다는 점입니다.

해결 방향:

/api/v1/**PUBLIC_URLS에서 제거하고, 정말 공개해야 하는 API만 개별 경로로 명시해야 합니다. 코디북 API는 인증이 필요한 사용자 리소스이므로 Security 필터에서 JWT 검증이 먼저 동작하게 두고, unauthenticated 요청이 401/403으로 떨어지는 테스트도 함께 추가하는 편이 안전합니다.

P2: 코디 생성 요청 길이 검증이 DB 컬럼 길이보다 느슨해 저장 단계에서 실패할 수 있습니다

src/main/java/com/closetnangam/be/domain/outfit/dto/request/OutfitCreateRequest.java:13부터 OutfitCreateRequest.java:26까지는 title, thumbnailUrl, situation, season@NotBlank만 적용합니다. 그런데 엔티티는 Outfit.java:33title을 100자, Outfit.java:39thumbnailUrl을 500자, Outfit.java:42Outfit.java:45situation/season을 50자로 제한합니다.

영향:

예를 들어 200자 title이나 80자 season은 Bean Validation을 통과한 뒤 JPA flush/DB constraint 단계에서 실패합니다. 클라이언트 입장에서는 입력 오류가 400으로 안정적으로 반환되지 않고, DB 예외 기반 500 응답이나 데이터베이스별 잘림 동작에 의존하게 됩니다.

해결 방향:

요청 DTO에 엔티티 컬럼과 같은 @Size(max = 100), @Size(max = 500), @Size(max = 50) 제약을 추가해 컨트롤러 진입 시점에 검증되게 해 주세요. thumbnailUrl은 필요하다면 URL 형식 검증도 함께 고려할 수 있습니다.


검증:

  • git diff --check origin/develop...HEAD: 통과
  • git merge-tree --write-tree origin/develop origin/feat/#47: 통과
  • ./gradlew compileJava --offline: 성공
  • ./gradlew test --offline: 성공
  • gh pr view --json mergeable: MERGEABLE

본 리뷰는 Codex를 사용해 작성했습니다.

@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown

⚠️ Claude 리뷰 생성 중 문제가 발생했습니다. Actions 로그를 확인해 주세요.

@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown

✅ 테스트 결과: 모든 테스트 통과

항목
전체 1
통과 1
실패 0
건너뜀 0

@jychoi0831 jychoi0831 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

현재 head commit c30b2dc 기준으로 확인했습니다.

이전 리뷰의 /api/v1/** 전체 공개 문제는 범위가 줄었고, OutfitCreateRequest 길이 검증도 추가된 것을 확인했습니다. 다만 아래 blocker가 여전히 남아 있습니다.

P1: 로그인 사용자 리소스인 코디북 API가 여전히 공개 경로로 열려 있습니다

src/main/java/com/closetnangam/be/global/config/SecurityConfig.java:35부터 PUBLIC_URLS/api/v1/outfit-books/**가 포함되어 있고, SecurityConfig.java:50에서 이 목록을 permitAll()로 처리합니다. 그런데 새 코디북 컨트롤러는 OutfitController.java:31, OutfitController.java:39, OutfitController.java:46, OutfitController.java:53의 모든 엔드포인트에서 현재 로그인한 사용자 기준으로 동작하며, 실제로 OutfitController.java:33, OutfitController.java:41, OutfitController.java:48, OutfitController.java:58에서 SecurityUtils.getCurrentUserId()를 호출합니다.

영향:

토큰이 없는 요청도 Spring Security에서 401/403으로 먼저 차단되지 않고 컨트롤러까지 도달합니다. 이 경우 SecurityUtils.getCurrentUserId()는 인증 principal이 없거나 Long이 아니면 IllegalStateException("인증 정보를 찾을 수 없습니다.")를 던지므로, 인증 실패가 정상적인 보안 응답이 아니라 서버 예외 흐름으로 처리될 수 있습니다. 더 근본적으로 코디북은 "현재 로그인한 사용자의" 리소스이므로 공개 URL 목록에 들어가면 안 됩니다.

해결 방향:

/api/v1/outfit-books/**PUBLIC_URLS에서 제거하고 .anyRequest().authenticated() 경로로 두어 JWT 필터/인증 실패 처리가 먼저 동작하게 해 주세요. 추가로 토큰 없이 GET /api/v1/outfit-booksPOST /api/v1/outfit-books 호출 시 401/403이 반환되는 보안 테스트가 있으면 같은 회귀를 막을 수 있습니다.


검증:

  • git diff --check origin/develop...HEAD: 통과
  • git merge-tree --write-tree origin/develop origin/feat/#47: 통과
  • ./gradlew compileJava --offline: 성공
  • ./gradlew test --offline: 성공
  • gh pr view --json mergeable: MERGEABLE

본 리뷰는 Codex를 사용해 작성했습니다.

@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown

⚠️ Claude 리뷰 생성 중 문제가 발생했습니다. Actions 로그를 확인해 주세요.

@github-actions

github-actions Bot commented Jun 1, 2026

Copy link
Copy Markdown

✅ 테스트 결과: 모든 테스트 통과

항목
전체 1
통과 1
실패 0
건너뜀 0

@jychoi0831 jychoi0831 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

현재 head commit ec33924 기준으로 확인했습니다.

추가 merge-blocking finding은 발견하지 못했습니다. 이전 리뷰의 코디북 API 공개 경로 문제는 /api/v1/outfit-books/**PUBLIC_URLS에서 제거되어 해결됐고, OutfitCreateRequest 길이 검증도 추가된 것을 확인했습니다.

검증:

  • git diff --check origin/develop...HEAD: 통과
  • git merge-tree --write-tree origin/develop origin/feat/#47: 통과
  • ./gradlew compileJava --offline: 성공
  • ./gradlew test --offline: 성공
  • gh pr view --json mergeable: MERGEABLE

잔여 리스크 또는 테스트 보강 권장:

  • SecurityConfig의 공개 경로가 /api/v1/auth/**로 넓어졌습니다. 현재는 local 프로파일의 mock-token만 해당하지만, 이후 /api/v1/auth 아래 인증 필요 API가 추가되면 의도치 않게 공개될 수 있으니 가능하면 필요한 엔드포인트만 명시하는 편이 안전합니다.
  • 토큰 없이 GET/POST /api/v1/outfit-books가 401로 떨어지고, 인증된 사용자는 본인 코디북만 접근 가능한지 보안 회귀 테스트를 추가하면 이번 이슈 재발을 막기 좋습니다.
  • OutfitCreateRequest에 리뷰 반영 과정의 대화형 주석이 남아 있어 머지 전 정리하면 코드 품질이 더 깔끔합니다.

본 리뷰는 Codex를 사용해 작성했습니다.

@seokminseok seokminseok merged commit 56cb882 into develop Jun 1, 2026
2 of 3 checks passed
@seokminseok seokminseok deleted the feat/#47 branch June 1, 2026 11:32
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.

feat/ 코디북 생성

2 participants