Skip to content

위시 등록·합치기·탈퇴의 폴더 연결 처리 (3단계) - #1271

Merged
sevineleven merged 3 commits into
devfrom
feat/1266-wish-folder-register-merge
Nov 2, 2026
Merged

sevineleven merged 3 commits into
devfrom
feat/1266-wish-folder-register-merge

Conversation

@sevineleven

Copy link
Copy Markdown
Collaborator

한눈에

위시를 담을 때 바로 폴더에 넣고, 위시가 합쳐져도 폴더에서 안 빠지게

  • 이전: 위시 등록 API 가 폴더를 받지 않음
    • 앱이 폴더 상세에서 링크 · 이미지로 새 위시를 담을 수 없음
    • 이미 담은 링크를 폴더에서 다시 담으면 409 로 거절
  • 이전: 파싱 뒤 같은 상품의 위시끼리 합쳐질 때 사라지는 위시의 폴더 연결이 남지 않음
    • 결과: 폴더에 넣은 상품이 폴더에서 빠져 보임
  • 위시 등록 API 가 폴더 id 를 받아 담는 순간 그 폴더에 넣음
  • 이미 담은 링크는 기존 위시를 그 폴더에 넣고 결과를 알려 줌
  • 위시가 합쳐지면 폴더 연결을 남는 위시로 옮김
  • 머지 직후 dev 자동 배포. DB 변경 없음

Situation

#1266

  • 위시 등록·합치기·탈퇴의 폴더 연결 처리 (3단계) #1266
  • 추가
    • 합침 사실은 이미 이벤트(ItemSlotMerged)로 발행되고 있음
      • 알림 · SSE 리스너는 커밋 뒤에 받음
      • 폴더 연결은 커밋 뒤에 옮기면 사이 구간에 지워진 위시를 가리키고, 옮기다 실패하면 연결이 사라짐
    • 이미지 확정 요청 DTO 를 토너먼트와 같이 씀
      • 폴더 필드를 얹으면 토너먼트 문서에도 보임

Task

#1266

Action

등록 때 폴더 지정

  • 링크 등록 · 이미지 확정 요청에 선택 필드 folderId
  • 등록과 같은 트랜잭션에서 새 위시를 폴더에 넣음
    • 회원 행 다음 폴더 행을 잠가 폴더 쓰기 API 와 같은 순서
  • 없는 폴더 · 남의 폴더는 등록 한도를 쓰기 전에 404 FOLDER-001
  • 이미지 확정은 위시 전용 요청 DTO 로 분리

이미 담은 링크 (디자인 기준)

요청 status folderResult wish.id
새 링크 201 null 새 위시
이미 담은 링크, folderId 없음 409 WISH-009 없음 없음
이미 담은 링크, 폴더에 없음 201 ADDED 기존 위시
이미 담은 링크, 이미 폴더에 있음 201 ALREADY_IN_FOLDER 기존 위시
  • 기존 위시를 넣는 경우는 새로 담는 것이 아니라 등록 한도 · 외부 유입 기록을 쓰지 않음
  • 같은 링크가 동시에 두 번 와서 둘째가 중복 검사를 통과해도, 잠금 뒤 기존 위시를 다시 찾아 그 위시를 넣음
선택지 장점 비용
항상 201 + folderResult (채택) 컨트롤러 관례(고정 status) 유지. 앱은 필드 하나로 분기 ALREADY_IN_FOLDER 는 만든 것이 없는데 201
기존 위시면 200 HTTP 의미가 정확 컨트롤러가 ResponseEntity 를 직접 돌려줘야 해 관례 예외. 앱이 status 와 필드를 함께 봄

합칠 때 폴더 연결 이관

  • 합침 이벤트를 동기 리스너로 받아 합치기 트랜잭션 안에서 옮김
    • 트랜잭션 밖에서는 못 돌게 막음(Propagation.MANDATORY)
    • 옮기다 실패하면 합치기도 함께 되돌아감
    • 메모 이관과 같은 시점
  • 남는 위시가 이미 그 폴더에 있으면 사라지는 위시의 연결만 지움
  • 옮길 폴더를 id 오름차순으로 잠금
    • 합치기는 위시 잠금 다음 폴더 잠금, 폴더 쓰기는 회원 잠금 다음 폴더 잠금이라 서로 기다리는 고리가 없음
  • 위시 모듈은 폴더를 모르고 이벤트만 발행. 의존은 폴더에서 위시 한 방향

Result

검증

  • 합치기 이관 통합 테스트 2건(옮김 · 남는 위시가 이미 폴더에 있음)
    • 리스너를 빼면 2건 모두 실패하는 것 확인 뒤 되돌림
  • 이미 담은 링크 세 경우와 남의 폴더 404 뒤 위시가 안 생기는지 (통합)

남는 것

  • 이미지 확정 + folderId 는 새로 만든 위시만 폴더에 넣음
    • 예전에 확정한 이미지는 폴더에 안 들어감
  • 위험: 위시 목록 폴더 필터·검색 추가 (2단계) #1270(2단계)과 위시 응답 · 서비스 · 문서 · 폴더 저장소가 겹쳐 나중에 머지되는 쪽이 충돌 정리
  • 위시 모듈의 폴더 인터페이스가 2단계 조회용과 이 PR 의 등록용 두 개가 됨
    • 둘 다 머지된 뒤 하나로 합칠지 결정

후속

  • 클라 공유: 등록 응답 folderResult 세 값과 의미

연관 이슈

- 링크 등록 · 이미지 확정 요청에 선택 필드 folderId 추가
  - 등록과 같은 트랜잭션에서 새 위시를 그 폴더에 넣음
  - 없는 폴더 · 남의 폴더는 한도를 쓰기 전에 404 FOLDER-001
  - 회원 행 다음 폴더 행을 잠가 폴더 쓰기와 같은 순서
- folderId 와 함께 이미 담은 링크를 담으면 409 대신 기존 위시를 폴더에 넣음
  - 응답 folderResult: ADDED · ALREADY_IN_FOLDER, wish.id 는 기존 위시
  - 응답 status 는 201 그대로. 결과는 folderResult 로 구분
  - 새로 담는 것이 아니라 한도 · 외부 유입 기록을 쓰지 않음
  - folderId 없으면 409 WISH-009 그대로
- 위시가 합쳐지면 폴더 연결을 남는 위시로 옮김
  - 합침 이벤트를 동기 리스너로 받아 합치기 트랜잭션 안에서 처리
    - 원인: 커밋 뒤 처리면 사이 구간에 지워진 위시를 가리키고 실패 시 연결이 사라짐
  - 남는 위시가 이미 그 폴더에 있으면 합쳐진 위시 연결만 지움
- 이미지 확정은 위시 전용 요청 DTO 로 분리
  - 원인: 토너먼트와 같이 쓰는 요청에 폴더 필드를 얹으면 토너먼트 문서에도 노출
- 리스너를 빼면 합치기 통합 테스트 2건이 실패하는 것 확인
@sevineleven sevineleven added the feat 외부 가시적 새 기능 label Nov 2, 2026
@sevineleven sevineleven linked an issue Nov 2, 2026 that may be closed by this pull request
@sevineleven sevineleven self-assigned this Nov 2, 2026
@coderabbitai

coderabbitai Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 41 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration
Commits

Reviewing files that changed from the base of the PR and between 7624ed2 and 1c8ee42.

Files selected for processing: 24
  • src/main/kotlin/com/depromeet/piki/folder/domain/FolderContents.kt
  • src/main/kotlin/com/depromeet/piki/folder/repository/FolderJpaRepository.kt
  • src/main/kotlin/com/depromeet/piki/folder/repository/FolderRepository.kt
  • src/main/kotlin/com/depromeet/piki/folder/repository/FolderRepositoryImpl.kt
  • src/main/kotlin/com/depromeet/piki/folder/repository/FolderWishJpaRepository.kt
  • src/main/kotlin/com/depromeet/piki/folder/repository/FolderWishRepository.kt
  • src/main/kotlin/com/depromeet/piki/folder/repository/FolderWishRepositoryImpl.kt
  • src/main/kotlin/com/depromeet/piki/folder/service/FolderWishLinker.kt
  • src/main/kotlin/com/depromeet/piki/folder/service/FolderWishMergeListener.kt
  • src/main/kotlin/com/depromeet/piki/wishlist/controller/WishlistApi.kt
  • src/main/kotlin/com/depromeet/piki/wishlist/controller/WishlistApiExamples.kt
  • src/main/kotlin/com/depromeet/piki/wishlist/controller/WishlistController.kt
  • src/main/kotlin/com/depromeet/piki/wishlist/controller/dto/WishImageConfirmRequest.kt
  • src/main/kotlin/com/depromeet/piki/wishlist/controller/dto/WishItemResponse.kt
  • src/main/kotlin/com/depromeet/piki/wishlist/controller/dto/WishlistRegisterRequest.kt
  • src/main/kotlin/com/depromeet/piki/wishlist/domain/WishFolderResult.kt
  • src/main/kotlin/com/depromeet/piki/wishlist/service/WishFolderLinker.kt
  • src/main/kotlin/com/depromeet/piki/wishlist/service/WishPersistenceService.kt
  • src/main/kotlin/com/depromeet/piki/wishlist/service/WishlistService.kt
  • src/main/kotlin/com/depromeet/piki/wishlist/service/dto/ConfirmWishImageRegistrationCommand.kt
  • src/main/kotlin/com/depromeet/piki/wishlist/service/dto/RegisterWishFromUrlCommand.kt
  • src/main/kotlin/com/depromeet/piki/wishlist/service/dto/WishResult.kt
  • src/test/kotlin/com/depromeet/piki/folder/controller/FolderWishRegisterIntegrationTest.kt
  • src/test/kotlin/com/depromeet/piki/folder/domain/FolderContentsTest.kt
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

Share

@github-actions

github-actions Bot commented Nov 2, 2026

Copy link
Copy Markdown

Discord 스레드 연동용 메타데이터입니다. discord-pr-bot 워크플로가 자동 생성하며, 수정·삭제하면 PR 과 Discord 알림 연동이 끊깁니다.

@sevineleven

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

- 2단계(#1270) 머지분과의 충돌 3곳은 양쪽을 모두 살림
  - WishResult · WishItemResponse · WishlistService
- 등록 응답에도 folderIds 를 채움
  - 링크 등록 · 이미 담은 링크 · 이미지 확정
  - 원인: 안 채우면 폴더를 지정해 담은 직후 folderIds 가 빈 배열로 나감
@sevineleven

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Nov 2, 2026 •

Copy link
Copy Markdown
Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@sevineleven
sevineleven merged commit bd1e039 into dev Nov 2, 2026
5 checks passed
@sevineleven
sevineleven deleted the feat/1266-wish-folder-register-merge branch November 2, 2026 10:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat 외부 가시적 새 기능

Projects

None yet

Development

Successfully merging this pull request may close these issues.

위시 등록·합치기·탈퇴의 폴더 연결 처리 (3단계)

1 participant