[hotfix] alias color 빠진 api 1개 수정 + category color 값을 반환해야하는 요구사항에 따라 코드 수정#214
Conversation
Walkthrough응답 DTO에 aliasColor/categoryColor 필드를 추가하고, 서비스 계층에서 해당 값을 채우도록 매핑을 확장했다. 카테고리의 별칭 색상을 조회하기 위해 포트/어댑터/레포지토리에 쿼리 메서드를 추가했다. 한 DTO는 빌더(@builder)로 전환되었고, 관련 서비스는 빌더 사용으로 변경되었다. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant RoomShowPlayingDetailViewService as Service(Playing)
participant RoomQueryPort as RoomQueryPort
participant RoomQueryPersistenceAdapter as Adapter
participant CategoryJpaRepository as CategoryRepo
Client->>Service(Playing): getPlayingRoomDetailView(roomId, userId)
Service(Playing)->>RoomQueryPort: findAliasColorOfCategory(room.category)
RoomQueryPort->>Adapter: findAliasColorOfCategory(category)
Adapter->>CategoryRepo: findAliasColorByValue(category.value)
CategoryRepo-->>Adapter: aliasColor
Adapter-->>RoomQueryPort: aliasColor
RoomQueryPort-->>Service(Playing): aliasColor
Service(Playing)-->>Client: RoomPlayingDetailViewResponse(..., categoryColor)
sequenceDiagram
participant Client
participant RoomShowRecruitingDetailViewService as Service(Recruiting)
participant RoomQueryPort as RoomQueryPort
participant RoomQueryPersistenceAdapter as Adapter
participant CategoryJpaRepository as CategoryRepo
Client->>Service(Recruiting): getRecruitingRoomDetailView(roomId, userId)
Service(Recruiting)->>RoomQueryPort: findAliasColorOfCategory(room.category)
RoomQueryPort->>Adapter: findAliasColorOfCategory(category)
Adapter->>CategoryRepo: findAliasColorByValue(category.value)
CategoryRepo-->>Adapter: aliasColor
Adapter-->>RoomQueryPort: aliasColor
RoomQueryPort-->>Service(Recruiting): aliasColor
Service(Recruiting)-->>Client: RoomRecruitingDetailViewResponse.builder().categoryColor(...).build()
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changes
Possibly related PRs
Suggested labels
Suggested reviewers
Poem
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
Test Results383 tests 383 ✅ 31s ⏱️ Results for commit a5ead8a. |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (9)
src/main/java/konkuk/thip/room/adapter/in/web/response/RoomRecruitingDetailViewResponse.java (1)
19-19: categoryColor 추가 OK. API 문서에 색상 포맷 명세(@Schema) 주석 추가 제안FE와의 계약을 명확히 하기 위해 색상 포맷(예: #RRGGBB)을 스키마에 명시해두는 것을 권장합니다.
아래와 같이 컴포넌트에 애너테이션을 부여하세요:
- String categoryColor, + @Schema(description = "카테고리 별칭 색상 코드(예: #RRGGBB)") + String categoryColor,추가로 파일 상단에 import가 필요합니다(선택 적용):
// 파일 상단 import 섹션에 추가 import io.swagger.v3.oas.annotations.media.Schema;src/main/java/konkuk/thip/room/adapter/in/web/response/RoomPlayingDetailViewResponse.java (1)
17-17: categoryColor 필드 추가 적절. 중복 매핑 로직의 공통화와 API 문서 주석 제안
- Recruiting/Playing 상세 모두에서 categoryColor를 채우는 로직이 생겼습니다. 서비스/매퍼 레벨에서 공통 함수로 추출하면 중복 제거와 유지보수성이 좋아집니다(예: Room -> categoryColor 매핑 유틸).
- 스키마에 색상 포맷을 명시하는 주석을 추가하는 것을 권장합니다.
스키마 주석 예:
- String categoryColor, + @Schema(description = "카테고리 별칭 색상 코드(예: #RRGGBB)") + String categoryColor,필요 시 import:
import io.swagger.v3.oas.annotations.media.Schema;src/main/java/konkuk/thip/room/adapter/in/web/response/RoomGetMemberListResponse.java (1)
18-19: aliasColor 필드 추가 적합. null 가능성과 문서화에 대한 간단한 가이드
- User.alias가 비어있는 경우를 고려해 null이 반환될 수 있음을 FE에 명확히 하거나, 서버에서 기본값을 정해주는 정책 합의가 필요합니다.
- API 스키마에 색상 포맷을 명시해 주세요.
스키마 주석 예:
- String aliasColor, + @Schema(description = "사용자 별칭(닉네임 테마) 색상 코드(예: #RRGGBB)") + String aliasColor,필요 시 import:
import io.swagger.v3.oas.annotations.media.Schema;src/main/java/konkuk/thip/room/application/port/out/RoomQueryPort.java (1)
41-45: 포트 메서드 네이밍/소속/반환 타입 개선(후속 리팩토링 제안)
- RoomQueryPort에 Category 관련 조회가 새로 추가되었는데, 개념적으로는 CategoryQueryPort가 더 적합합니다. hotfix 이후 포트 분리/이동을 고려해 주세요.
String보다는ColorCode같은 값 객체를 반환하는 편이 유효성(형식 검증, 표준화)과 변경 내성에 유리합니다.- 메서드명도 동작을 드러내도록
getCategoryAliasColorOrThrow(Category category)등으로 구체화하면 의도가 명확해집니다.- 성능: 상세 보기 호출마다 별도 쿼리를 타는 구조라면, 카테고리 값->색상 매핑을 Caffeine 등으로 캐싱(TTL/사이즈 제한)하거나, 원본 Room 조회 시 조인으로 함께 가져오도록 쿼리를 확장하면 RTT를 줄일 수 있습니다.
원하시면 캐시 도입(Caffeine)을 위한 설정/코드 스니펫과, 포트/어댑터 계층 분리 계획안을 정리해 드리겠습니다.
src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryPersistenceAdapter.java (1)
108-115: 메서드 계약/네이밍 및 캐싱 고려 — ‘find’가 예외를 던지는 계약과 어울리지 않습니다.
- 현재 ‘findAliasColorOfCategory’가 값을 못 찾으면 예외를 던집니다. ‘find’ 대신 ‘get...OrThrow’로 바꾸거나 Optional을 반환하는 쪽이 계약상 더 명확합니다.
- 동일 카테고리 값에 대한 반복 조회가 잦을 수 있으니, 간단한 캐싱을 붙이면 DB 부하와 레이턴시를 줄일 수 있습니다.
아래처럼 캐시를 붙이는 소규모 변경을 제안드립니다(캐싱 미활성화 시에도 무해합니다).
@@ - @Override - public String findAliasColorOfCategory(Category category) { - return categoryJpaRepository.findAliasColorByValue(category.getValue()).orElseThrow( - () -> new EntityNotFoundException(ErrorCode.CATEGORY_NOT_FOUND) - ); - } + @Override + @org.springframework.cache.annotation.Cacheable(cacheNames = "categoryAliasColorByValue", key = "#category.value") + public String findAliasColorOfCategory(Category category) { + return categoryJpaRepository.findAliasColorByValue(category.getValue()) + .orElseThrow(() -> new EntityNotFoundException(ErrorCode.CATEGORY_NOT_FOUND)); + }추가로, 예외 코드가 "카테고리 자체 없음"과 "별칭 색상 매핑 없음"을 동일하게 다루고 있습니다. 분리된 에러 코드(e.g., CATEGORY_ALIAS_COLOR_NOT_FOUND)를 두면 운영 관찰성이 좋아집니다.
src/main/java/konkuk/thip/room/application/service/RoomShowPlayingDetailViewService.java (1)
71-71: 빌더 내 동기 쿼리 호출 분리 권장 — 가독성과 예외 처리 지점 명확화.
빌더 체인 안에서 쿼리 메서드를 직접 호출하면 예외 처리/로깅이 어려워집니다. 값을 미리 조회해 지역 변수로 전달하세요.@@ public class RoomShowPlayingDetailViewService implements RoomShowPlayingDetailViewUseCase { - return RoomPlayingDetailViewResponse.builder() + final String categoryColor = roomQueryPort.findAliasColorOfCategory(room.getCategory()); // TODO : 리팩토링 대상 + return RoomPlayingDetailViewResponse.builder() @@ - .categoryColor(roomQueryPort.findAliasColorOfCategory(room.getCategory())) // TODO : 리펙토링 대상 + .categoryColor(categoryColor) .build();참고: 색상 누락 상황에서 예외가 치명적이라면, 여기에서 안전한 기본값(예: "#000000")으로 폴백하는 정책도 검토해 주세요.
src/main/java/konkuk/thip/room/adapter/out/persistence/repository/category/CategoryJpaRepository.java (2)
12-12: 도메인 키 기반 탐색 메서드 추가 적절
Category.value는 조회의 주키로 자주 쓰일 가능성이 높습니다. 파생 쿼리 도입은 타당합니다. value 컬럼에 유니크 인덱스가 없다면 추가를 권장합니다.
15-18: JPQL 시그니처/네이밍 정교화 제안 + 인덱스 고려
- 메서드명과 파라미터명을 더 구체적으로 맞추면 검색/사용 맥락이 분명해집니다.
- where 절에서 c.value를 필터로 사용하므로 DB에 인덱스가 없으면 색상 조회에 불필요한 풀스캔이 발생할 수 있습니다.
다음과 같이 시그니처를 명확화하는 것을 고려해 주세요(연쇄 수정 필요).
- @Query("select a.color " + - "from CategoryJpaEntity c join c.aliasForCategoryJpaEntity a " + - "where c.value = :categoryValue") - Optional<String> findAliasColorByValue(@Param("categoryValue") String categoryValue); + @Query("select a.color " + + "from CategoryJpaEntity c join c.aliasForCategoryJpaEntity a " + + "where c.value = :value") + Optional<String> findAliasColorByCategoryValue(@Param("value") String value);운영 DB에서 Category.value 컬럼에 인덱스/유니크 제약이 없다면 추가를 권장합니다. 카디널리티가 높을수록 색상 조회의 P95/P99 레이턴시에 유의미한 개선이 있습니다.
src/main/java/konkuk/thip/room/application/service/RoomShowRecruitingDetailViewService.java (1)
65-65: 모집 마감 안내 포맷 재검토 — DateUtil.formatAfterTime의 음수/0인 경우 "??" 노출 위험
현재 구현은 시작일이 지났을 때 "??"가 반환됩니다. 실제 사용자 화면에는 "마감됨" 등의 안내가 적절합니다. 서비스 레벨에서 폴백하거나, DateUtil 자체를 개선하는 것이 좋아 보입니다.원하시면 DateUtil에 "formatAfterTimeOrClosed" 형태의 안전한 API를 추가하는 수정안도 제안드릴 수 있습니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
src/main/java/konkuk/thip/room/adapter/in/web/response/RoomGetMemberListResponse.java(1 hunks)src/main/java/konkuk/thip/room/adapter/in/web/response/RoomPlayingDetailViewResponse.java(1 hunks)src/main/java/konkuk/thip/room/adapter/in/web/response/RoomRecruitingDetailViewResponse.java(2 hunks)src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryPersistenceAdapter.java(3 hunks)src/main/java/konkuk/thip/room/adapter/out/persistence/repository/category/CategoryJpaRepository.java(1 hunks)src/main/java/konkuk/thip/room/application/port/out/RoomQueryPort.java(1 hunks)src/main/java/konkuk/thip/room/application/service/RoomGetMemberListService.java(1 hunks)src/main/java/konkuk/thip/room/application/service/RoomShowPlayingDetailViewService.java(3 hunks)src/main/java/konkuk/thip/room/application/service/RoomShowRecruitingDetailViewService.java(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: seongjunnoh
PR: THIP-TextHip/THIP-Server#113
File: src/main/java/konkuk/thip/recentSearch/adapter/out/persistence/RecentSearchCommandPersistenceAdapter.java:38-44
Timestamp: 2025-07-30T14:05:04.945Z
Learning: seongjunnoh는 코드 최적화 제안에 대해 구체적인 기술적 근거와 효율성 차이를 이해하고 싶어하며, 성능 개선 방식에 대한 상세한 설명을 선호한다.
Learnt from: seongjunnoh
PR: THIP-TextHip/THIP-Server#93
File: src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryPersistenceAdapter.java:49-114
Timestamp: 2025-07-28T16:44:31.224Z
Learning: seongjunnoh는 코드 중복 문제에 대한 리팩토링 제안을 적극적으로 수용하고 함수형 인터페이스를 활용한 해결책을 선호한다.
Learnt from: seongjunnoh
PR: THIP-TextHip/THIP-Server#195
File: src/main/java/konkuk/thip/feed/application/mapper/FeedQueryMapper.java:0-0
Timestamp: 2025-08-13T05:22:32.287Z
Learning: seongjunnoh는 데이터 무결성과 중복 방지에 대한 고민이 깊으며, LinkedHashSet을 활용한 중복 제거와 순서 보장을 동시에 달성하는 솔루션을 선호한다.
Learnt from: seongjunnoh
PR: THIP-TextHip/THIP-Server#112
File: src/main/java/konkuk/thip/feed/adapter/out/persistence/repository/FeedQueryRepositoryImpl.java:272-272
Timestamp: 2025-07-30T10:44:34.115Z
Learning: seongjunnoh는 피드 커서 페이지네이션에서 LocalDateTime 단일 커서 방식을 선호하며, 복합 키 기반 커서보다 구현 단순성과 성능을 우선시한다.
🧬 Code Graph Analysis (2)
src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryPersistenceAdapter.java (1)
src/main/java/konkuk/thip/common/exception/EntityNotFoundException.java (1)
EntityNotFoundException(5-10)
src/main/java/konkuk/thip/room/application/service/RoomShowRecruitingDetailViewService.java (1)
src/main/java/konkuk/thip/common/util/DateUtil.java (1)
DateUtil(12-62)
🔇 Additional comments (3)
src/main/java/konkuk/thip/room/adapter/in/web/response/RoomRecruitingDetailViewResponse.java (1)
7-7: 직접 생성자 호출 잔존 여부 확인 완료
직접 생성자 호출(new RoomRecruitingDetailViewResponse(…),new RoomPlayingDetailViewResponse(…))는 더 이상 존재하지 않으며, 모든 사용처가 @builder로 마이그레이션된 것을 확인했습니다.src/main/java/konkuk/thip/room/application/service/RoomGetMemberListService.java (1)
55-55: NPE 방어 및 중복 접근 제거 제안
RoomGetMemberListService.java(약 55행 부근)에서user.getAlias()에 여러 번 접근하고 있어,user또는alias가 null일 경우 NPE가 발생할 수 있습니다. 임시 변수로 뽑아 두고 null-safe 하게 매핑하거나, 도메인에서alias가 항상 존재함을 명시적으로 보장해주세요.– 위치
- 파일: src/main/java/konkuk/thip/room/application/service/RoomGetMemberListService.java
- 범위:
roomParticipants.stream().map(…)내부 빌더 호출 부분– 최소 변경 예시
- return RoomGetMemberListResponse.MemberSearchResult.builder() - .userId(userId) - .nickname(user.getNickname()) - .imageUrl(user.getAlias().getImageUrl()) - .aliasName(user.getAlias().getValue()) - .aliasColor(user.getAlias().getColor()) - .followerCount(user.getFollowerCount()) - .build(); + final var alias = user.getAlias(); + return RoomGetMemberListResponse.MemberSearchResult.builder() + .userId(userId) + .nickname(user.getNickname()) + .imageUrl(alias != null ? alias.getImageUrl() : null) + .aliasName(alias != null ? alias.getValue() : null) + .aliasColor(alias != null ? alias.getColor() : null) + .followerCount(user.getFollowerCount()) + .build();– 도메인 불변이 보장된다면 아래처럼 의도를 명시할 수도 있습니다.
Objects.requireNonNull(user, "user must not be null. userId=" + userId); Objects.requireNonNull(user.getAlias(), "alias must not be null. userId=" + userId);alias가 null이 될 수 있는지 도메인 제약을 확인한 뒤 위 중 적절한 방어 로직 또는
requireNonNull을 적용해주세요.src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryPersistenceAdapter.java (1)
3-4: 예외 매핑 추가 적절 — NotFound를 명시적으로 표현한 점 좋습니다.
CATEGORY_NOT_FOUND로 명확히 매핑되어 있어 장애 시 원인 파악이 용이합니다.
| public class RoomQueryPersistenceAdapter implements RoomQueryPort { | ||
|
|
||
| private final RoomJpaRepository roomJpaRepository; | ||
| private final CategoryJpaRepository categoryJpaRepository; |
There was a problem hiding this comment.
🛠️ Refactor suggestion
CategoryJpaRepository 의존 추가는 타당하지만, 쿼리 경로 최적화를 고려해 주세요.
현재 서비스 레이어에서 카테고리 색상 조회가 개별 DB 왕복을 유발합니다. Room 관련 조회(projection/DTO)에 categoryColor를 조인해 한 번에 가져오도록 리포지토리 쿼리를 확장하면, 상세 화면 1회 호출당 추가 쿼리 1회 비용을 제거할 수 있습니다.
원하시면 RoomJpaRepository에 카테고리 색상 조인을 포함한 전용 프로젝션(예: RoomDetailProjection{..., categoryColor})을 추가하는 패치를 제안드릴게요.
🤖 Prompt for AI Agents
In
src/main/java/konkuk/thip/room/adapter/out/persistence/RoomQueryPersistenceAdapter.java
around line 30, adding CategoryJpaRepository is acceptable but causes per-room
DB roundtrips for category color; instead extend RoomJpaRepository to return a
projection/DTO that includes categoryColor (e.g., RoomDetailProjection { ...,
String categoryColor }), implement a repository query (JPQL/@Query or join
fetch) that joins Room -> Category and selects the category color into that
projection, update the adapter/service to use this new projection for room
detail queries and remove the per-room CategoryJpaRepository lookups so the
color is retrieved in a single DB call.
| return RoomRecruitingDetailViewResponse.builder() | ||
| .isHost(participants.isHostOfRoom(userId)) | ||
| .isJoining(participants.isJoiningToRoom(userId)) | ||
| .roomId(room.getId()) | ||
| .roomName(room.getTitle()) | ||
| .roomImageUrl(room.getCategory().getImageUrl()) | ||
| .isPublic(room.isPublic()) | ||
| .progressStartDate(DateUtil.formatDate(room.getStartDate())) | ||
| .progressEndDate(DateUtil.formatDate(room.getEndDate())) | ||
| .recruitEndDate(DateUtil.formatAfterTime(room.getStartDate())) | ||
| .category(room.getCategory().getValue()) | ||
| .categoryColor(roomQueryPort.findAliasColorOfCategory(room.getCategory())) // TODO : 리펙토링 대상 | ||
| .roomDescription(room.getDescription()) | ||
| .memberCount(participants.calculateMemberCount()) | ||
| .recruitCount(room.getRecruitCount()) | ||
| .isbn(book.getIsbn()) | ||
| .bookImageUrl(book.getImageUrl()) | ||
| .bookTitle(book.getTitle()) | ||
| .authorName(book.getAuthorName()) | ||
| .bookDescription(book.getDescription()) | ||
| .publisher(book.getPublisher()) | ||
| .recommendRooms(recommendRooms) | ||
| .build(); |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Builder 전 데이터 조회 분리 및 중복 제거 — 두 서비스에서 동일 패턴 반복
- Playing/Recruiting 상세 모두에서 categoryColor 조회가 동일하게 반복됩니다. 지역 변수로 분리하고, 공통 유틸/컴포넌트로 추출하면 재사용성과 테스트 용이성이 좋아집니다.
간단한 로컬 정리 예시:
@@
- return RoomRecruitingDetailViewResponse.builder()
+ final String categoryColor = roomQueryPort.findAliasColorOfCategory(room.getCategory()); // TODO : 리펙토링 대상
+ return RoomRecruitingDetailViewResponse.builder()
@@
- .categoryColor(roomQueryPort.findAliasColorOfCategory(room.getCategory())) // TODO : 리펙토링 대상
+ .categoryColor(categoryColor)
.roomDescription(room.getDescription())더 나아가 CategoryColorProvider 컴포넌트를 도입해(인터페이스 + 기본 구현) 두 서비스에서 주입받아 사용하면, 추후 캐싱/폴백 정책을 한 곳에서 관리할 수 있습니다. 원하시면 해당 컴포넌트 초안까지 만들어 드리겠습니다.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| return RoomRecruitingDetailViewResponse.builder() | |
| .isHost(participants.isHostOfRoom(userId)) | |
| .isJoining(participants.isJoiningToRoom(userId)) | |
| .roomId(room.getId()) | |
| .roomName(room.getTitle()) | |
| .roomImageUrl(room.getCategory().getImageUrl()) | |
| .isPublic(room.isPublic()) | |
| .progressStartDate(DateUtil.formatDate(room.getStartDate())) | |
| .progressEndDate(DateUtil.formatDate(room.getEndDate())) | |
| .recruitEndDate(DateUtil.formatAfterTime(room.getStartDate())) | |
| .category(room.getCategory().getValue()) | |
| .categoryColor(roomQueryPort.findAliasColorOfCategory(room.getCategory())) // TODO : 리펙토링 대상 | |
| .roomDescription(room.getDescription()) | |
| .memberCount(participants.calculateMemberCount()) | |
| .recruitCount(room.getRecruitCount()) | |
| .isbn(book.getIsbn()) | |
| .bookImageUrl(book.getImageUrl()) | |
| .bookTitle(book.getTitle()) | |
| .authorName(book.getAuthorName()) | |
| .bookDescription(book.getDescription()) | |
| .publisher(book.getPublisher()) | |
| .recommendRooms(recommendRooms) | |
| .build(); | |
| // Extract categoryColor once to remove duplication and improve testability | |
| final String categoryColor = roomQueryPort.findAliasColorOfCategory(room.getCategory()); // TODO : 리펙토링 대상 | |
| return RoomRecruitingDetailViewResponse.builder() | |
| .isHost(participants.isHostOfRoom(userId)) | |
| .isJoining(participants.isJoiningToRoom(userId)) | |
| .roomId(room.getId()) | |
| .roomName(room.getTitle()) | |
| .roomImageUrl(room.getCategory().getImageUrl()) | |
| .isPublic(room.isPublic()) | |
| .progressStartDate(DateUtil.formatDate(room.getStartDate())) | |
| .progressEndDate(DateUtil.formatDate(room.getEndDate())) | |
| .recruitEndDate(DateUtil.formatAfterTime(room.getStartDate())) | |
| .category(room.getCategory().getValue()) | |
| .categoryColor(categoryColor) // TODO : 리펙토링 대상 | |
| .roomDescription(room.getDescription()) | |
| .memberCount(participants.calculateMemberCount()) | |
| .recruitCount(room.getRecruitCount()) | |
| .isbn(book.getIsbn()) | |
| .bookImageUrl(book.getImageUrl()) | |
| .bookTitle(book.getTitle()) | |
| .authorName(book.getAuthorName()) | |
| .bookDescription(book.getDescription()) | |
| .publisher(book.getPublisher()) | |
| .recommendRooms(recommendRooms) | |
| .build(); |
🤖 Prompt for AI Agents
In
src/main/java/konkuk/thip/room/application/service/RoomShowRecruitingDetailViewService.java
around lines 56 to 78, the categoryColor is being looked up inline in the
builder causing duplicated lookup logic across services; extract the category
color lookup into a local variable (e.g., String categoryColor =
roomQueryPort.findAliasColorOfCategory(room.getCategory())) and use that
variable in the builder, and then refactor by introducing a
CategoryColorProvider interface with a default implementation (or a simple
utility) that encapsulates roomQueryPort.findAliasColorOfCategory(...) so this
service and the similar Playing/Recruiting detail service can accept the
provider via constructor injection and call
provider.getCategoryColor(room.getCategory()), centralizing the logic for easier
reuse, testing, caching and future fallback handling.
#️⃣ 연관된 이슈
📝 작업 내용
@hd0rable @buzz0331 현재 Alias, Category 는 도메인이 아니라, 각각 User, Room에 속하는 Value 로 분류된 상황인데, 모집중/진행중인 방 상세보기 api의 response 에 category에 해당하는 color 값을 반환해야하는 요구사항이 생김으로써
하도록 구현하였습니다.
현재 도메인 레벨에서는 [Alias, Category 의 연관관계를 고려 X, 그리고 각각을 엔티티가 아니라 Value로 분류] 하지만,
JPA 레벨에서는 [Alias, Category를 각각 엔티티로 분류, 서로 연관관계 존재] 하는 상황이라서 일단 임시 방편으로 요구사항을 만족하기 위해 위 방식으로 수정하였습니다
추후에 JPA 엔티티 및 DB 테이블 구조를 수정하여 Alias, Category를 DB 테이블에서 탈락시킨다고 해도, category의 color 값을 반환해야하는 요구사항으로 인해
위와 같은 방법을 고려해야 할 것 같습니다!! 일단 hotfix이니 바로 머지하고 노션에 위 내용 추가해놓겠습니다!
📸 스크린샷
💬 리뷰 요구사항
📌 PR 진행 시 이러한 점들을 참고해 주세요