Conversation
feat(auth): 로그아웃 기능 완성
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
크리에이터 프로필(공개/내 프로필) 조회 및 내 프로필 수정 API를 신규로 구현하고, 관련 연동(gRPC/Kafka/보안/예외) 및 기존 user/auth 서비스의 DTO/UseCase 시그니처를 커맨드/쿼리 패턴으로 정리한 PR입니다.
Changes:
creator서비스에 프로필 조회/수정 + 커서 기반 목록/검색 API, JPA 영속/보안 필터, 외부 서비스(gRPC) 조회 포트/어댑터를 추가user서비스에 정지/정지해제 도메인 상태/이벤트를 도입하고, RepositoryPort에 pessimistic lock 조회 메서드 및 DTO 패키지 구조를 정리auth서비스에 커맨드 DTO 도입 및 Kafka 핸들러/컨트롤러 시그니처를 조정, SonarCloud 워크플로우에 Java binaries 설정을 추가
Reviewed changes
Copilot reviewed 58 out of 78 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| services/user/src/main/java/kr/magicbox/user/domain/exception/UserSessionNotActiveException.java | 세션 종료 예외 신규 |
| services/user/src/main/java/kr/magicbox/user/domain/exception/UserNotBannedException.java | unban 전용 예외 신규 |
| services/user/src/main/java/kr/magicbox/user/domain/exception/UserBannedException.java | 정지 사용자 예외 신규 |
| services/user/src/main/java/kr/magicbox/user/domain/exception/UserAlreadyInactiveException.java | (삭제) 기존 비활성 예외 제거 |
| services/user/src/main/java/kr/magicbox/user/domain/event/UserUnbannedEvent.java | 유저 정지해제 도메인 이벤트 추가 |
| services/user/src/main/java/kr/magicbox/user/domain/event/UserDomainEventType.java | USER_UNBANNED 타입 추가 |
| services/user/src/main/java/kr/magicbox/user/domain/enums/UserStatus.java | 상태값 변경(INACTIVE 제거, BANNED 추가) |
| services/user/src/main/java/kr/magicbox/user/domain/aggregate/User.java | activate/ban/unban/delete 도메인 메서드 정리 |
| services/user/src/main/java/kr/magicbox/user/application/service/WithdrawUserService.java | 커맨드 기반 탈퇴 + 락 조회 적용 |
| services/user/src/main/java/kr/magicbox/user/application/service/UserQueryService.java | 쿼리 객체 기반 프로필 조회로 변경 |
| services/user/src/main/java/kr/magicbox/user/application/service/UserCommandService.java | 커맨드 객체 기반 프로필 수정으로 변경 |
| services/user/src/main/java/kr/magicbox/user/application/service/UnbanUserService.java | 정지 해제 유스케이스 구현 추가 |
| services/user/src/main/java/kr/magicbox/user/application/service/ManageUserSessionService.java | 세션 시작/종료 커맨드화 + 예외 변경 |
| services/user/src/main/java/kr/magicbox/user/application/service/LoginService.java | Repository 메서드명(save/update) 정리 반영 |
| services/user/src/main/java/kr/magicbox/user/application/service/CheckUserActiveService.java | active 체크 쿼리 객체화 |
| services/user/src/main/java/kr/magicbox/user/application/service/BanUserService.java | ban 도메인 메서드/업데이트 메서드명 반영 |
| services/user/src/main/java/kr/magicbox/user/application/port/out/UserRepositoryPort.java | lock 조회 메서드 + save/update 네이밍 변경 |
| services/user/src/main/java/kr/magicbox/user/application/port/out/ReviewQueryPort.java | UserReviewResult 패키지 변경 반영 |
| services/user/src/main/java/kr/magicbox/user/application/port/in/WithdrawUserUseCase.java | WithdrawUserCommand로 시그니처 변경 |
| services/user/src/main/java/kr/magicbox/user/application/port/in/UserQueryUseCase.java | GetUserProfileQuery로 시그니처 변경 |
| services/user/src/main/java/kr/magicbox/user/application/port/in/UserCommandUseCase.java | UpdateUserProfileCommand로 시그니처 변경 |
| services/user/src/main/java/kr/magicbox/user/application/port/in/UnbanUserUseCase.java | 정지 해제 유스케이스 포트 추가 |
| services/user/src/main/java/kr/magicbox/user/application/port/in/ManageUserSessionUseCase.java | 세션 커맨드(시작/종료)로 변경 |
| services/user/src/main/java/kr/magicbox/user/application/port/in/LoadUserCredentialUseCase.java | LoadUserCredential DTO 패키지 변경 |
| services/user/src/main/java/kr/magicbox/user/application/port/in/CheckUserActiveUseCase.java | CheckUserActiveQuery로 변경 |
| services/user/src/main/java/kr/magicbox/user/application/port/in/BanUserUseCase.java | 포맷 정리(실질 변경 없음) |
| services/user/src/main/java/kr/magicbox/user/application/dto/UpdateUserProfileCommand.java | (삭제) 구 DTO 제거 |
| services/user/src/main/java/kr/magicbox/user/application/dto/result/UserReviewResult.java | result 패키지로 이동 |
| services/user/src/main/java/kr/magicbox/user/application/dto/result/LoadUserCredentialResult.java | result 패키지로 이동 |
| services/user/src/main/java/kr/magicbox/user/application/dto/result/GetUserProfileResult.java | result 패키지로 이동 |
| services/user/src/main/java/kr/magicbox/user/application/dto/query/GetUserProfileQuery.java | 프로필 조회 쿼리 DTO 추가 |
| services/user/src/main/java/kr/magicbox/user/application/dto/query/CheckUserActiveQuery.java | active 체크 쿼리 DTO 추가 |
| services/user/src/main/java/kr/magicbox/user/application/dto/command/WithdrawUserCommand.java | 탈퇴 커맨드 DTO 추가 |
| services/user/src/main/java/kr/magicbox/user/application/dto/command/UpdateUserProfileCommand.java | 프로필 수정 커맨드 DTO 추가 |
| services/user/src/main/java/kr/magicbox/user/application/dto/command/UnbanUserCommand.java | (현재 미사용) unban 커맨드 DTO |
| services/user/src/main/java/kr/magicbox/user/application/dto/command/StartSessionCommand.java | 세션 시작 커맨드 DTO 추가 |
| services/user/src/main/java/kr/magicbox/user/application/dto/command/LoadUserCredentialCommand.java | command 패키지로 이동 |
| services/user/src/main/java/kr/magicbox/user/application/dto/command/EndSessionCommand.java | 세션 종료 커맨드 DTO 추가 |
| services/user/src/main/java/kr/magicbox/user/application/dto/command/BanUserCommand.java | (현재 미사용) ban 커맨드 DTO |
| services/user/src/main/java/kr/magicbox/user/adapter/out/persistence/UserJpaAdapter.java | lock 조회/메서드명 변경 반영 |
| services/user/src/main/java/kr/magicbox/user/adapter/out/persistence/repository/UserJpaRepository.java | pessimistic lock 쿼리 추가 |
| services/user/src/main/java/kr/magicbox/user/adapter/out/persistence/entity/UserEntity.java | @Version 제거 + status 업데이트 반영 |
| services/user/src/main/java/kr/magicbox/user/adapter/out/communication/grpc/ReviewQueryGrpcAdapter.java | UserReviewResult 패키지 변경 |
| services/user/src/main/java/kr/magicbox/user/adapter/in/web/UserQueryController.java | GetUserProfileQuery 사용하도록 변경 |
| services/user/src/main/java/kr/magicbox/user/adapter/in/web/UserCommandController.java | Update/Withdraw 커맨드 적용 |
| services/user/src/main/java/kr/magicbox/user/adapter/in/web/exception/handler/GlobalExceptionHandler.java | optimistic lock 예외 핸들러 제거 |
| services/user/src/main/java/kr/magicbox/user/adapter/in/web/dto/response/GetUserProfileResponse.java | response 패키지/DTO 변경 반영 |
| services/user/src/main/java/kr/magicbox/user/adapter/in/web/dto/request/UpdateUserProfileRequest.java | request 패키지/커맨드 생성 변경 |
| services/user/src/main/java/kr/magicbox/user/adapter/in/web/AdminUserCommandController.java | unban 엔드포인트 추가 |
| services/user/src/main/java/kr/magicbox/user/adapter/in/kafka/AuthEventKafkaListener.java | 세션 커맨드 적용 |
| services/user/src/main/java/kr/magicbox/user/adapter/in/grpc/UserGrpcService.java | CheckUserActiveQuery 적용 |
| services/creator/src/main/resources/application-prod.yml | creator prod 설정 신규 |
| services/creator/src/main/resources/application-local.yml | creator local 설정 확장 |
| services/creator/src/main/resources/application-dev.yml | creator dev 설정 신규 |
| services/creator/src/main/proto/subscribe.proto | 구독 서비스 gRPC 스텁 정의 추가 |
| services/creator/src/main/proto/shortform.proto | 숏폼 서비스 gRPC 스텁 정의 추가 |
| services/creator/src/main/proto/review.proto | 리뷰 서비스 gRPC 스텁 정의 추가 |
| services/creator/src/main/proto/release.proto | 릴리즈 서비스 gRPC 스텁 정의 추가 |
| services/creator/src/main/java/kr/magicbox/creator/global/exception/SystemError.java | 5xx 전용 예외 추가 |
| services/creator/src/main/java/kr/magicbox/creator/global/exception/BusinessException.java | 4xx 전용 예외 추가 |
| services/creator/src/main/java/kr/magicbox/creator/global/exception/BaseException.java | 공통 베이스 예외 추가 |
| services/creator/src/main/java/kr/magicbox/creator/global/configuration/PropertiesConfiguration.java | @ConfigurationPropertiesScan 추가 |
| services/creator/src/main/java/kr/magicbox/creator/domain/vo/UserId.java | VO 추가 |
| services/creator/src/main/java/kr/magicbox/creator/domain/vo/Nickname.java | VO 추가 |
| services/creator/src/main/java/kr/magicbox/creator/domain/vo/CreatorId.java | VO 추가 |
| services/creator/src/main/java/kr/magicbox/creator/domain/exception/InvalidReviewRatingException.java | 별점 검증 예외 추가 |
| services/creator/src/main/java/kr/magicbox/creator/domain/exception/InvalidFieldException.java | 필드 검증 예외 추가 |
| services/creator/src/main/java/kr/magicbox/creator/domain/exception/CreatorNotFoundException.java | NotFound 예외 추가 |
| services/creator/src/main/java/kr/magicbox/creator/domain/exception/CreatorNotBannedException.java | unban 검증 예외 추가 |
| services/creator/src/main/java/kr/magicbox/creator/domain/exception/CreatorAlreadyExistsException.java | 중복 등록 예외 추가 |
| services/creator/src/main/java/kr/magicbox/creator/domain/enums/MagicGenre.java | 장르 enum 추가 |
| services/creator/src/main/java/kr/magicbox/creator/domain/enums/CreatorStatus.java | 상태 enum 추가 |
| services/creator/src/main/java/kr/magicbox/creator/domain/constants/CreatorPolicyConstants.java | 정책 상수 추가 |
| services/creator/src/main/java/kr/magicbox/creator/domain/aggregate/Creator.java | Creator 도메인 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/service/UpdateCreatorProfileService.java | 내 프로필 수정 유스케이스 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/service/SearchCreatorsService.java | 크리에이터 검색 유스케이스 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/service/GetMyCreatorProfileService.java | 내 프로필 조회 유스케이스 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/service/GetCreatorProfileService.java | 공개 프로필 조회 유스케이스 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/service/GetAllCreatorsService.java | 전체 목록 커서 조회 유스케이스 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/port/out/SubscribeQueryPort.java | 구독 조회 포트 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/port/out/ShortformQueryPort.java | 숏폼 조회 포트 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/port/out/ReviewRatingQueryPort.java | 리뷰 별점 조회 포트 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/port/out/ReleaseQueryPort.java | 릴리즈 조회 포트 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/port/out/CreatorRepositoryPort.java | Creator 저장소 포트 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/port/in/UpdateCreatorProfileUseCase.java | 수정 유스케이스 포트 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/port/in/SearchCreatorsUseCase.java | 검색 유스케이스 포트 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/port/in/GetMyCreatorProfileUseCase.java | 내 조회 유스케이스 포트 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/port/in/GetCreatorProfileUseCase.java | 공개 조회 유스케이스 포트 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/port/in/GetAllCreatorsUseCase.java | 목록 유스케이스 포트 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/dto/result/ReviewRating.java | 별점 VO/DTO 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/dto/result/CreatorSearchResult.java | 검색 결과 DTO 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/dto/result/CreatorPublicProfileResult.java | 공개 프로필 결과 DTO 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/dto/result/CreatorProfileResult.java | 프로필 DTO 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/dto/result/CreatorMyProfileResult.java | 내 프로필 DTO 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/dto/query/GetMyCreatorProfileQuery.java | 쿼리 DTO 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/dto/query/GetCreatorProfileQuery.java | 쿼리 DTO 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/dto/query/GetAllCreatorsQuery.java | 커서 쿼리 DTO 추가 |
| services/creator/src/main/java/kr/magicbox/creator/application/dto/command/UpdateCreatorProfileCommand.java | 수정 커맨드 DTO 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/out/persistence/repository/CreatorJpaRepository.java | JPA 리포지토리/락/커서 쿼리 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/out/persistence/mapper/CreatorMapper.java | 도메인-엔티티 매퍼 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/out/persistence/entity/CreatorEntity.java | Creator 엔티티 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/out/persistence/entity/BaseEntity.java | sonyflake+auditing 베이스 엔티티 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/out/persistence/CreatorJpaAdapter.java | 저장소 어댑터 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/out/persistence/configuration/JpaConfiguration.java | JPA auditing 활성화 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/out/communication/ServiceHost.java | gRPC 채널 호스트 enum 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/out/communication/grpc/SubscribeGrpcAdapter.java | subscribe gRPC 어댑터 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/out/communication/grpc/ShortformQueryGrpcAdapter.java | shortform gRPC 어댑터 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/out/communication/grpc/ReviewQueryGrpcAdapter.java | review gRPC 어댑터 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/out/communication/grpc/ReleaseQueryGrpcAdapter.java | release gRPC 어댑터 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/out/communication/grpc/exception/SubscribeServiceUnavailableException.java | 장애 예외 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/out/communication/grpc/exception/ShortformServiceUnavailableException.java | 장애 예외 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/out/communication/grpc/exception/ReviewServiceUnavailableException.java | 장애 예외 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/out/communication/grpc/exception/ReleaseServiceUnavailableException.java | 장애 예외 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/in/web/validation/CursorSizeValidator.java | size 검증기 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/in/web/validation/CursorSize.java | size 제약 애노테이션 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/in/web/exception/handler/GlobalExceptionHandler.java | 전역 예외 처리 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/in/web/exception/handler/ErrorResponse.java | 에러 응답 DTO 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/in/web/dto/response/CursorResponse.java | 커서 응답 래퍼 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/in/web/dto/response/CreatorSearchResponse.java | 검색 응답 DTO 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/in/web/dto/response/CreatorProfileResponse.java | 공개 프로필 응답 DTO 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/in/web/dto/response/CreatorMyProfileResponse.java | 내 프로필 응답 DTO 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/in/web/dto/request/UpdateCreatorProfileRequest.java | 내 프로필 수정 요청 DTO 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/in/web/CreatorQueryController.java | 조회 API 컨트롤러 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/in/web/CreatorCommandController.java | 수정/탈퇴 API 컨트롤러 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/in/web/constants/CursorConstants.java | 커서 상수 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/in/security/properties/TrustedIpProperties.java | Trusted IP 설정 바인딩 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/in/security/filter/UserInfoExtractFilter.java | X-User-Id 추출 필터 추가 |
| services/creator/src/main/java/kr/magicbox/creator/adapter/in/security/configuration/SecurityConfiguration.java | stateless 보안 설정 추가 |
| services/creator/build.gradle | protobuf/grpc/cloud 의존성 추가 |
| services/auth/src/main/java/kr/magicbox/auth/domain/exception/UserInactiveException.java | 비활성 사용자 예외 신규 |
| services/auth/src/main/java/kr/magicbox/auth/domain/exception/UserBannedException.java | (현재 미사용) 정지 예외 신규 |
| services/auth/src/main/java/kr/magicbox/auth/domain/exception/InActiveUserException.java | (삭제) 기존 예외 제거 |
| services/auth/src/main/java/kr/magicbox/auth/application/service/RefreshTokenService.java | refresh 커맨드 적용 |
| services/auth/src/main/java/kr/magicbox/auth/application/service/LogoutService.java | logout 커맨드 적용 + 예외 교체 |
| services/auth/src/main/java/kr/magicbox/auth/application/service/LoginService.java | DTO 패키지 변경 반영 |
| services/auth/src/main/java/kr/magicbox/auth/application/service/HandleUserWithdrawnService.java | Kafka 처리 커맨드 적용 |
| services/auth/src/main/java/kr/magicbox/auth/application/service/HandleUserBannedService.java | Kafka 처리 커맨드 적용 |
| services/auth/src/main/java/kr/magicbox/auth/application/port/out/UserCredentialPort.java | UserResult 패키지 변경 반영 |
| services/auth/src/main/java/kr/magicbox/auth/application/port/in/RefreshTokenUseCase.java | RefreshTokenCommand 적용 |
| services/auth/src/main/java/kr/magicbox/auth/application/port/in/LogoutUseCase.java | LogoutCommand 적용 |
| services/auth/src/main/java/kr/magicbox/auth/application/port/in/LoginUseCase.java | LoginCommand 패키지 변경 반영 |
| services/auth/src/main/java/kr/magicbox/auth/application/port/in/HandleUserWithdrawnUseCase.java | HandleUserWithdrawnCommand 적용 |
| services/auth/src/main/java/kr/magicbox/auth/application/port/in/HandleUserBannedUseCase.java | HandleUserBannedCommand 적용 |
| services/auth/src/main/java/kr/magicbox/auth/application/dto/result/UserResult.java | result 패키지로 이동 |
| services/auth/src/main/java/kr/magicbox/auth/application/dto/result/TokenResult.java | result 패키지로 이동 |
| services/auth/src/main/java/kr/magicbox/auth/application/dto/result/IssueTokenResult.java | result 패키지로 이동 |
| services/auth/src/main/java/kr/magicbox/auth/application/dto/command/RefreshTokenCommand.java | refresh 커맨드 추가 |
| services/auth/src/main/java/kr/magicbox/auth/application/dto/command/LogoutCommand.java | logout 커맨드 추가 |
| services/auth/src/main/java/kr/magicbox/auth/application/dto/command/LoginCommand.java | command 패키지로 이동 |
| services/auth/src/main/java/kr/magicbox/auth/application/dto/command/HandleUserWithdrawnCommand.java | withdraw 이벤트 커맨드 추가 |
| services/auth/src/main/java/kr/magicbox/auth/application/dto/command/HandleUserBannedCommand.java | banned 이벤트 커맨드 추가 |
| services/auth/src/main/java/kr/magicbox/auth/adapter/out/communication/grpc/UserGrpcAdapter.java | UserResult 패키지 변경 반영 |
| services/auth/src/main/java/kr/magicbox/auth/adapter/in/web/dto/response/AccessTokenResponse.java | response 패키지로 이동 |
| services/auth/src/main/java/kr/magicbox/auth/adapter/in/web/dto/request/LoginRequest.java | request 패키지로 이동 |
| services/auth/src/main/java/kr/magicbox/auth/adapter/in/web/AuthCommandController.java | refresh/logout 커맨드 적용 |
| services/auth/src/main/java/kr/magicbox/auth/adapter/in/security/oauth2/OAuth2LoginSuccessHandler.java | UserResult 패키지 변경 반영 |
| services/auth/src/main/java/kr/magicbox/auth/adapter/in/kafka/UserEventKafkaListener.java | Kafka 핸들링 커맨드 적용 |
| .github/workflows/sonarcloud-analyze.yml | JDK21 설정 + sonar.java.binaries 주입 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| UserId userId = query.userId(); | ||
| Creator creator = creatorRepositoryPort.findByNickname(query.nickname()) | ||
| .orElseThrow(CreatorNotFoundException::new); | ||
|
|
||
| Long creatorId = creator.getUserId(); | ||
|
|
||
| return new CreatorPublicProfileResult( |
There was a problem hiding this comment.
creatorId로 외부(구독/릴리즈/리뷰/숏폼) 서비스를 조회해야 하는데, 현재 creator.getUserId()(사용자 ID)를 사용하고 있습니다. 크리에이터 엔티티의 PK(예: creator.getId().value() 또는 CreatorId)를 사용하도록 수정하지 않으면 잘못된 대상에 대해 집계가 조회됩니다.
| Creator creator = creatorRepositoryPort.findByUserId(query.userId()) | ||
| .orElseThrow(CreatorNotFoundException::new); | ||
|
|
||
| Long creatorId = creator.getUserId(); | ||
|
|
||
| return new CreatorMyProfileResult( | ||
| creator.getNickname(), |
There was a problem hiding this comment.
creatorId로 외부(구독/릴리즈/리뷰/숏폼) 서비스를 조회해야 하는데, 현재 creator.getUserId()(사용자 ID)를 사용하고 있습니다. creator.getId().value() 등 실제 크리에이터 ID를 사용하도록 수정해야 응답이 올바릅니다.
| public record UpdateCreatorProfileRequest( | ||
| @Size(min = CreatorPolicyConstants.nicknameMinLength, max = CreatorPolicyConstants.nicknameMaxLength) String nickname, | ||
| @Size(max = 50) String tagline, | ||
| String profileImageUrl, | ||
| @Size(max = 500) String introduction, | ||
| @NotEmpty Set<@NotNull MagicGenre> genres | ||
| ) { | ||
|
|
||
| public UpdateCreatorProfileCommand toCommand(UserId userId) { | ||
| return new UpdateCreatorProfileCommand( | ||
| userId, | ||
| Nickname.of(nickname), | ||
| tagline, | ||
| profileImageUrl, | ||
| introduction, | ||
| genres | ||
| ); |
There was a problem hiding this comment.
nickname 필드가 null일 수 있도록(@SiZe만 사용) 열려 있는데, toCommand()에서 무조건 Nickname.of(nickname)를 호출해 null 요청 시 예외가 발생합니다. 닉네임이 필수라면 @NotBlank/@NotNull로 명시하고, 선택값이라면 nickname == null ? null : Nickname.of(nickname)처럼 커맨드에 null을 전달하도록 수정해주세요.
|
|
||
| Long userIdLong = Long.valueOf(userIdRequestHeader); | ||
| UserId userId = UserId.of(userIdLong); | ||
| log.info(String.valueOf(userId)); |
There was a problem hiding this comment.
요청마다 userId를 INFO 레벨로 로깅하면 트래픽이 많은 환경에서 로그 볼륨이 과도해지고(또는 PII 노출), 운영 비용/보안 이슈가 될 수 있습니다. 필요하다면 DEBUG로 낮추거나 제거하고, 추적이 목적이면 request-id 등 비식별 값을 로깅하는 편이 안전합니다.
| log.info(String.valueOf(userId)); |
| public Long getUserId() { | ||
| return this.userId.value(); | ||
| } | ||
|
|
||
| public String getNickname() { | ||
| return this.nickname.value(); | ||
| } |
There was a problem hiding this comment.
userId/nickname 필드는 VO 타입인데, 공개 getter가 getUserId(): Long, getNickname(): String로 값만 노출되어 이름과 타입이 직관적이지 않습니다(예: 실제 크리에이터 ID와 혼동하기 쉬움). VO를 그대로 반환하는 getter를 유지하고 값 접근은 getUserIdValue()/getNicknameValue()처럼 별도 메서드로 분리하는 편이 오용을 줄입니다.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
f-lab-ted
left a comment
There was a problem hiding this comment.
DDD 관점에서 헥사고널 아키텍처의 core/port/adapter 레이어 경계가 잘 설정되어 있고, 도메인 어그리거트(Creator)가 명확하게 정의되어 있습니다. 하지만 타입 안전성, 보안 설정, Command 패턴 일관성 등에서 개선이 필요한 부분이 있습니다.
|
|
||
| @Override | ||
| protected void doFilterInternal(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull FilterChain filterChain) throws ServletException, IOException { | ||
| String clientIp = request.getRemoteAddr(); |
There was a problem hiding this comment.
프록시/로드밸런서 환경에서 request.getRemoteAddr()는 실제 클라이언트 IP가 아닌 프록시 IP를 반환할 수 있습니다. X-Forwarded-For 헤더를 확인하거나 Spring Security의 ForwardedHeaderFilter를 고려하세요.
현재 코드:
String clientIp = request.getRemoteAddr();권장:
String clientIp = getClientIpAddress(request);
private String getClientIpAddress(HttpServletRequest request) {
String xForwardedFor = request.getHeader("X-Forwarded-For");
if (xForwardedFor != null && !xForwardedFor.isEmpty() && !"unknown".equalsIgnoreCase(xForwardedFor)) {
return xForwardedFor.split(",")[0].trim();
}
return request.getRemoteAddr();
}There was a problem hiding this comment.
ForwardedHeaderFilter를 사용해보겠습니다!
| long subscriberCount, | ||
| long releaseCount, | ||
| ReviewRating reviewRating, | ||
| List<Object> releases, |
There was a problem hiding this comment.
List 타입 대신 구체적인 DTO 타입을 사용하세요.
현재 코드:
List<Object> releases,
List<Object> shortForms,권장:
List<ReleaseResponse> releases,
List<ShortformResponse> shortForms,Object 타입을 사용하면 컴파일 타임에 타입 안전성을 보장할 수 없고, API 명세가 불명확해집니다. Release, Shortform에 대한 전용 DTO를 정의하여 사용하세요.
There was a problem hiding this comment.
아이구.. 이런 수정하겠습니다!
| long subscriberCount, | ||
| long releaseCount, | ||
| ReviewRating reviewRating, | ||
| List<Object> releases, |
There was a problem hiding this comment.
CreatorProfileResponse와 동일하게 List 타입을 구체적인 DTO 타입으로 변경하세요.
List<ReleaseResponse> releases,
List<ShortformResponse> shortForms,There was a problem hiding this comment.
아이구.. 이런 수정하겠습니다!
|
|
||
| @Builder | ||
| public record UpdateCreatorProfileRequest( | ||
| @Size(min = CreatorPolicyConstants.NICKNAME_MIN_LENGTH, max = CreatorPolicyConstants.NICKNAME_MAX_LENGTH) String nickname, |
There was a problem hiding this comment.
nickname 필드의 @NotNull/@notempty 유효성 검사가 누락되었습니다. 현재 @SiZe만 적용되어 있어 null 값이 허용됩니다. nickname이 필수인지 선택 사항인지 명확히 하고 유효성 검사를 추가하세요.
현재:
@Size(min = CreatorPolicyConstants.NICKNAME_MIN_LENGTH, max = CreatorPolicyConstants.NICKNAME_MAX_LENGTH) String nickname,권장 (필수인 경우):
@NotNull
@Size(min = CreatorPolicyConstants.NICKNAME_MIN_LENGTH, max = CreatorPolicyConstants.NICKNAME_MAX_LENGTH) String nickname,
|



📌 관련 이슈
📝 변경 사항 요약
작업 유형
(기능 단위 완료 후 PR)(버그 1개 = PR 1개)(작업 단위 완료 후 PR)(작업 단위 완료 후 PR)변경 내용
변경 이유
✅ 테스트 체크리스트
📸 스크린샷 / 로그
펼쳐보기
🔄 동작 플로우 (Mermaid)
%%{init: {'flowchart': {'useMaxWidth': true, 'htmlLabels': true}} }%% flowchart TD A[프로필 조회] --> B[Creator 조회] B --> C[외부 지표 조회] C --> D[응답 조합] E[프로필 수정] --> F[입력 검증] F --> G[프로필 업데이트] G --> H[수정 응답]💬 리뷰어에게
크리에이터 프로필 조회/수정 API 구현 범위를 중심으로 리뷰 부탁드립니다.