-
Notifications
You must be signed in to change notification settings - Fork 3
[MERGE] 다른 사람 시리즈 조회 API 제작 #438
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
* [FEAT/#423] - 다른 사람 마이페이지 '여기서 저는요' 모달 조회 * [FEAT/#423] - 끓인팟 요약 조회: 팟 이름이랑 팟 멤버인지 여부 (boolean) 추가 * [FEAT/#423] - 권한 위임 API 오류 수정 * [FEAT/#423] - 팟 멤버 정보 조회 API role 에러 수정 * [FEAT/#423] - 팟 멤버 정보 조회 API role 에러 수정 * [Feat/#423] api 수정 (#425) * [FEAT/#423] - 다른 사람 마이페이지 '여기서 저는요' 모달 조회 * [FEAT/#423] - 끓인팟 요약 조회: 팟 이름이랑 팟 멤버인지 여부 (boolean) 추가 * [FEAT/#423] - 권한 위임 API 오류 수정 * [FEAT/#423] - 여기서 저는요 작성 및 수정 API 버그 수정 --------- Co-authored-by: jjaeroong <133083872+jjaeroong@users.noreply.github.com> Co-authored-by: Hyun <71479783+Hyun0828@users.noreply.github.com>
* [Feat/#423] api 수정 (#425) * [FEAT/#423] - 다른 사람 마이페이지 '여기서 저는요' 모달 조회 * [FEAT/#423] - 끓인팟 요약 조회: 팟 이름이랑 팟 멤버인지 여부 (boolean) 추가 * [FEAT/#423] - 권한 위임 API 오류 수정 * [FEAT/#423] - 여기서 저는요 작성 및 수정 API 버그 수정 * [Feat/#423] 어필하기 api 수정 * [FEAT/#423] - 다른 사람 마이페이지 '여기서 저는요' 모달 조회 * [FEAT/#423] - 끓인팟 요약 조회: 팟 이름이랑 팟 멤버인지 여부 (boolean) 추가 * [FEAT/#423] - 권한 위임 API 오류 수정 * [FEAT/#423] - 팟 멤버 정보 조회 API role 에러 수정 * [FEAT/#423] - 팟 멤버 정보 조회 API role 에러 수정 * [Feat/#423] api 수정 (#425) * [FEAT/#423] - 다른 사람 마이페이지 '여기서 저는요' 모달 조회 * [FEAT/#423] - 끓인팟 요약 조회: 팟 이름이랑 팟 멤버인지 여부 (boolean) 추가 * [FEAT/#423] - 권한 위임 API 오류 수정 * [FEAT/#423] - 여기서 저는요 작성 및 수정 API 버그 수정 --------- Co-authored-by: jjaeroong <133083872+jjaeroong@users.noreply.github.com> Co-authored-by: Hyun <71479783+Hyun0828@users.noreply.github.com> * [FIX/#423] - 팟 상세보기 + 지원자 목록 조회 API에 IsSaved가 반영되도록 수정 --------- Co-authored-by: jjaeroong <133083872+jjaeroong@users.noreply.github.com> Co-authored-by: Hyun <71479783+Hyun0828@users.noreply.github.com>
Walkthrough다른 사용자의 시리즈 목록 조회용 GET /feeds/series/{user_id} 엔드포인트와 대응 서비스 메서드를 추가했다. 팟 지원 상세 조회에 저장 여부(isSaved) 조회 로직을 포함했다. 팟 어필 업데이트는 현재 사용자 객체 기반 조회로 전환했고, 컨트롤러의 Operation 요약 문구를 변경했다. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Client
participant FC as FeedController
participant FQS as FeedQueryService
participant UR as UserRepository
participant SR as SeriesRepository
Client->>FC: GET /feeds/series/{user_id}
FC->>FQS: getOtherSeries(userId)
FQS->>UR: findById(userId)
alt user not found
FQS-->>FC: throw USER_NOT_FOUND
FC-->>Client: 404 ApiResponse
else user found
FQS->>SR: findAllByUser(user)
SR-->>FQS: List<Series>
FQS-->>FC: Map<seriesId, comment>
FC-->>Client: 200 ApiResponse<Map<Long,String>>
end
sequenceDiagram
autonumber
actor Client
participant PMC as PotMemberController
participant PMCS as PotMemberCommandServiceImpl
participant AS as AuthService
participant PMR as PotMemberRepository
Client->>PMC: PATCH /pots/{potId}/appeal
PMC->>PMCS: updateAppealContent(potId, dto)
PMCS->>AS: getCurrentUser()
AS-->>PMCS: User
PMCS->>PMR: findByPotPotIdAndUser(potId, user)
alt not found
PMCS-->>PMC: throw POT_MEMBER_NOT_FOUND
PMC-->>Client: 404
else found
PMCS->>PMR: save(updated PotMember)
PMCS-->>PMC: success
PMC-->>Client: 200
end
sequenceDiagram
autonumber
actor Client
participant PAQS as PotApplicationQueryServiceImpl
participant PSR as PotSaveRepository
Client->>PAQS: getPotDetailsAndApplicants(potId)
PAQS->>PSR: existsByUserAndPot_PotId(user, potId)
PSR-->>PAQS: boolean isSaved
PAQS-->>Client: PotDetailResponseDto(..., isSaved)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested reviewers
Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ 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
Status, Documentation and Community
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/main/java/stackpot/stackpot/pot/service/potMember/PotMemberCommandServiceImpl.java (1)
98-106: 필수:appealContent유효성 검증 및 XSS 방지 정책 적용서비스 레벨과 DTO/컨트롤러에서 아래 사항을 반드시 반영해 주세요.
UpdateAppealRequestDto.java(src/main/java/.../UpdateAppealRequestDto.java)
appealContent필드에 Bean Validation 애노테이션 추가@NotBlank(message = "어필 내용은 필수입니다.") @Size(max = 500, message = "어필 내용은 최대 500자까지 허용됩니다.") private String appealContent;- 필요하다면 DTO 클래스에
@Validated또는 컨트롤러 메서드에@Valid적용 여부 재확인
PotMemberController.java(src/main/java/.../PotMemberController.java)
@RequestBody @Valid UpdateAppealRequestDto requestDto사용으로 유효성 검증이 트리거되는지 확인
PotMemberCommandServiceImpl.java(src/main/java/.../PotMemberCommandServiceImpl.java)
- 저장 직전에 입력값 트리밍 및 XSS 방지 처리
String cleaned = HtmlUtils.htmlEscape(appealContent.trim()); potMember.setAppealContent(cleaned);- OWASP Java HTML Sanitizer 등 별도 라이브러리 도입 검토
엔티티 매핑 및 DB
@Column(length = 500)등 데이터베이스 컬럼 길이 제한 반영 검토위 변경으로 빈 문자열, 과도한 길이 입력을 차단하고, HTML/스크립트 인젝션을 방어할 수 있습니다.
🧹 Nitpick comments (11)
src/main/java/stackpot/stackpot/pot/service/potApplication/PotApplicationQueryServiceImpl.java (2)
68-69: existsBy… 사용은 적절하나, ID 기반 시그니처와 인덱스 고려를 권장합니다
- 현재
existsByUserAndPot_PotId(user, potId)는 JPA가user엔티티 프록시를 터치할 수 있습니다. 가능하면 기본키 기반 메서드가 더 가볍고 안전합니다.- 저장 테이블에
(user_id, pot_id)복합 인덱스(및 유니크 제약)를 두면 exists 쿼리 성능과 데이터 정합성에 도움이 됩니다.적용 예시(Repository 메서드가 없다면 추가 필요):
- boolean isSaved = potSaveRepository.existsByUserAndPot_PotId(user, potId); + boolean isSaved = potSaveRepository.existsByUser_IdAndPot_PotId(user.getId(), potId);Repository 인터페이스에 다음 시그니처 추가 필요:
boolean existsByUser_IdAndPot_PotId(Long userId, Long potId);
47-49: 엔티티 equals 비교 대신 ID 비교로 통일 권장
!pot.getUser().equals(user)는 프록시/equals 오버라이드 구현에 따라 미묘한 버그를 유발할 수 있습니다. 동일 파일 하단에서는 ID 비교를 사용 중이므로 위 로직도 ID 비교로 통일하면 일관성과 안정성이 올라갑니다.- if (!pot.getUser().equals(user)) { + if (!pot.getUser().getId().equals(user.getId())) {src/main/java/stackpot/stackpot/feed/service/FeedQueryService.java (1)
16-16: 새 인터페이스 메서드 추가 방향 OK — 명세와 반환 타입에 대한 간단한 문서화 제안다른 유저의 시리즈 조회를 위한
getOtherSeries(Long userId)추가는 컨트롤러 변경과 잘 맞습니다. 다만 반환 타입이Map<Long, String>(ID→코멘트)로 순서 보장이 없으니, 호출측에서 순서를 기대한다면 LinkedHashMap 또는 DTO 리스트로의 전환을 고려해 주세요. Javadoc으로 동작, 정렬 보장 여부를 명시하면 혼선을 줄일 수 있습니다.src/main/java/stackpot/stackpot/pot/controller/PotMemberController.java (1)
48-48: Operation 요약 문구를 더 명확하고 일관된 용어로 교체 제안현재 요약: “여기서 저는요 작성 및 수정 API”는 다소 구어체이며 맥락 없이 읽히기 쉽습니다. 기존 문서 톤과 맞추어 다음과 같이 간결화하면 좋겠습니다.
- @Operation(summary = "여기서 저는요 작성 및 수정 API") + @Operation(summary = "어필(자기소개) 작성/수정 API")src/main/java/stackpot/stackpot/feed/service/FeedQueryServiceImpl.java (1)
314-326: 중복 로직 최소화 및 순서 안정성을 위한 리팩터링 제안현 구현은
getMySeries()와 거의 동일한 로직을 반복하며,Collectors.toMap기본 구현은 HashMap으로 순서가 보장되지 않습니다. 다음을 권장합니다:
- 공통 헬퍼로 중복 제거.
- LinkedHashMap 수집으로 삽입 순서 유지(또는 Repository 레벨에서 정렬).
- 읽기 전용 트랜잭션 힌트(optional): dirty checking 방지.
변경 최소안(순서 안정성):
- return userSeriesList.stream() - .collect(Collectors.toMap( - Series::getSeriesId, - Series::getComment - )); + return userSeriesList.stream() + .collect(Collectors.toMap( + Series::getSeriesId, + Series::getComment, + (a, b) -> a, + java.util.LinkedHashMap::new + ));중복 제거 예시(클래스 내부에 추가):
// 공통 빌더 private Map<Long, String> buildSeriesMap(List<Series> seriesList) { return seriesList.stream().collect(Collectors.toMap( Series::getSeriesId, Series::getComment, (a, b) -> a, LinkedHashMap::new )); }그리고 두 메서드에서 사용:
// getMySeries() return buildSeriesMap(seriesRepository.findAllByUser(user)); // getOtherSeries() return buildSeriesMap(seriesRepository.findAllByUser(user));추가로, 불필요한 User 엔티티 로드를 줄이려면 Repository에
findAllByUser_Id(Long userId)형태가 있다면 이를 활용해 다음처럼 단축 가능합니다:List<Series> userSeriesList = seriesRepository.findAllByUser_Id(userId);(없다면 메서드 추가를 고려해 주세요.)
src/main/java/stackpot/stackpot/feed/controller/FeedController.java (1)
171-179: 엔드포인트/변수 표기 일관성 및 파라미터 문서화 제안
- 같은 컨트롤러 내에서 기존 경로 변수는
feedId(camelCase)를 사용 중인데, 신규는{user_id}(snake_case)입니다. 일관성을 위해{userId}로 통일을 권장합니다.- Swagger 파라미터 설명을 추가하면 사용성이 좋아집니다.
변경 예시:
- @GetMapping("/series/{user_id}") + @GetMapping("/series/{userId}") @Operation(summary = "다른 사람 Series 조회 API", description = "다른 사람의 Series List를 조회합니다.") @ApiErrorCodeExamples({ ErrorStatus.USER_NOT_FOUND }) - public ResponseEntity<ApiResponse<Map<Long, String>>> getSeries(@PathVariable("user_id") Long userId) { + public ResponseEntity<ApiResponse<Map<Long, String>>> getSeries(@PathVariable("userId") Long userId) { Map<Long, String> seriesMap = feedQueryService.getOtherSeries(userId); return ResponseEntity.ok(ApiResponse.onSuccess(seriesMap)); }Swagger 파라미터 설명 추가 예시:
@Operation( summary = "다른 사람 Series 조회 API", description = "다른 사용자의 Series 목록(ID→코멘트)을 반환합니다.", parameters = { @Parameter(name = "userId", description = "조회 대상 사용자 ID", required = true) } )src/main/java/stackpot/stackpot/pot/service/potMember/PotMemberCommandServiceImpl.java (5)
104-106: JPA 더티 체킹으로 save 호출 생략 가능Line 104~106: 같은 트랜잭션에서 조회한 엔티티에 단순 필드 변경만 한다면
save없이 커밋 시점에 flush되어 반영됩니다. 불필요한 merge 비용을 줄일 수 있습니다.- potMember.setAppealContent(appealContent); - potMemberRepository.save(potMember); + potMember.setAppealContent(appealContent); // @Transactional 범위 내: JPA dirty checking으로 커밋 시 반영
3-3: 트랜잭션 애노테이션 혼용(jakarta vs spring) — 하나로 통일 권장Line 3에서는
jakarta.transaction.Transactional을 import하고, Line 109~110에서는org.springframework.transaction.annotation.TransactionalFQCN을 사용 중입니다. 롤백 옵션, 팀 컨벤션 및 가시성을 고려해 Spring의@Transactional로 통일하는 것을 권장합니다.- import jakarta.transaction.Transactional; + import org.springframework.transaction.annotation.Transactional;- @org.springframework.transaction.annotation.Transactional + @TransactionalAlso applies to: 109-110
48-50: 예외 타입/에러 코드 일관화 제안Line 48~50: Pot 미존재 시 현재는
IllegalArgumentException("해당 팟을 찾을 수 없습니다.")를 던지지만, 동일 클래스의 다른 메서드에서는PotHandler(ErrorStatus.POT_NOT_FOUND)를 사용합니다. API 응답 규격 일관성을 위해 아래와 같이 통일을 권장합니다.- Pot pot = potRepository.findById(potId) - .orElseThrow(() -> new IllegalArgumentException("해당 팟을 찾을 수 없습니다.")); + Pot pot = potRepository.findById(potId) + .orElseThrow(() -> new PotHandler(ErrorStatus.POT_NOT_FOUND));
46-46: 변수명 오타 정정: potCreatUser → potCreatorUser가독성과 검색 편의성을 위해 변수명을 수정하는 것을 제안합니다. 사용 위치(Line 79)도 함께 변경되어야 합니다.
- User potCreatUser = authService.getCurrentUser(); + User potCreatorUser = authService.getCurrentUser();- PotMember member = potMemberConverter.toEntity(potCreatUser, pot, null, true); + PotMember member = potMemberConverter.toEntity(potCreatorUser, pot, null, true);Also applies to: 79-79
60-60: 네이밍 정확도: approvedApplicantIds → approvedApplicationIds
contains비교가application.getApplicationId()를 대상으로 하므로, 변수명이 실제 의도를 반영하지 않습니다. 혼동 방지를 위해 다음과 같이 수정 권장합니다.- List<Long> approvedApplicantIds = requestDto.getApplicantIds(); + List<Long> approvedApplicationIds = requestDto.getApplicantIds();- if (approvedApplicantIds.contains(application.getApplicationId())) { + if (approvedApplicationIds.contains(application.getApplicationId())) {Also applies to: 66-66
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (6)
src/main/java/stackpot/stackpot/feed/controller/FeedController.java(1 hunks)src/main/java/stackpot/stackpot/feed/service/FeedQueryService.java(1 hunks)src/main/java/stackpot/stackpot/feed/service/FeedQueryServiceImpl.java(1 hunks)src/main/java/stackpot/stackpot/pot/controller/PotMemberController.java(1 hunks)src/main/java/stackpot/stackpot/pot/service/potApplication/PotApplicationQueryServiceImpl.java(3 hunks)src/main/java/stackpot/stackpot/pot/service/potMember/PotMemberCommandServiceImpl.java(1 hunks)
🔇 Additional comments (4)
src/main/java/stackpot/stackpot/pot/service/potApplication/PotApplicationQueryServiceImpl.java (2)
39-40: isSaved 계산을 위한 Repository 주입 추가, 방향성 적절합니다읽기 전용 조회 경로에서 저장 여부를 판단하기 위해 PotSaveRepository를 주입한 것은 책임 분리에 부합합니다. 현재 @requiredargsconstructor로 안전하게 주입되고 있어 유지보수성도 좋습니다.
76-76: Converter 시그니처 동기화 완료PotDetailConverter의
toPotDetailResponseDto메서드 정의부와 모든 호출부가 동일한 파라미터 순서 및 개수로 변경된 것을 확인했습니다. 런타임 파라미터 순서 오류는 발생하지 않습니다.확인된 위치:
- src/main/java/stackpot/stackpot/pot/converter/PotDetailConverter.java:31 (메서드 정의)
- src/main/java/stackpot/stackpot/pot/service/potApplication/PotApplicationQueryServiceImpl.java:76 (호출)
- src/main/java/stackpot/stackpot/pot/service/pot/PotQueryServiceImpl.java:103 (호출)
추가 조치 불필요합니다.
src/main/java/stackpot/stackpot/feed/service/FeedQueryServiceImpl.java (1)
316-318: 접근 제어/프라이버시 요구사항 확인 권장다른 사용자의 시리즈를 누구나 조회 가능한가요? 차단/비공개 설정, 탈퇴/정지 사용자, 미인증 사용자 접근 등 정책 적용 필요 여부를 확인해 주세요. 필요 시 권한 체크를 추가해야 합니다.
src/main/java/stackpot/stackpot/pot/service/potMember/PotMemberCommandServiceImpl.java (1)
99-103: 현재 사용자 엔티티 기반 조회 + Optional.orElseThrow 적용: 적절합니다Line 99~103:
authService.getCurrentUser()로User엔티티를 받아findByPotPotIdAndUser(...)로 조회하고, 미존재 시PotHandler(ErrorStatus.POT_MEMBER_NOT_FOUND)를 던지는 흐름이 명확하고 일관적입니다.
PR 타입(하나 이상의 PR 타입을 선택해주세요)
반영 브랜치
dev -> main
작업 내용
다른 사람 시리즈 조회 API 제작
Summary by CodeRabbit