Repository navigation
[Feat]#62 퀘스티 기본 아이템 7종 지연 지급 · 상점 배경 카테고리 추가 - #63
Merged
Merged
Conversation
기본 보유 7종·상점 배경 5종 정의, 목록 외 활성 아이템은 비활성화 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HtgegmjNs3gAc6qNCTekNa
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HtgegmjNs3gAc6qNCTekNa
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HtgegmjNs3gAc6qNCTekNa
INSERT ... SELECT의 ON DUPLICATE KEY UPDATE id가 모호하다는 실DB 오류를 user_items.id로 한정해 수정. 구매 통합 테스트는 비활성화된 GOLDEN_CROWN 대신 COZY_CAFE(320P) 기준으로 변경 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HtgegmjNs3gAc6qNCTekNa
정상 상태(전부 보유)에서 호출마다 ON DUPLICATE KEY가 기존 행에 X-lock을 잡던 문제를 SELECT 단계에서 미보유분만 고르도록 수정. 비활성 아이템이 보유 목록·장착에서 빠지는지, 시더 재실행 시 updated_at이 그대로인지 실DB 테스트 추가 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HtgegmjNs3gAc6qNCTekNa
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
#️⃣ 연관된 이슈
📝 작업 내용
프론트 확정 사항(꾸미기 아이템 7종은 기본 보유, 아이템 상점은 배경 5종만)에 맞춰 서버 마스터 데이터와 지급 경로를 정리했습니다. 기존엔
shop_items에 기본 아이템이 4종뿐이고 이름도 달랐으며, 배경 카테고리가 없고,is_default아이템을user_items에 넣어주는 코드가 없어 프론트가 장착·구매 상태를 서버에 저장할 수 없었습니다.BACKGROUND카테고리 추가:ItemCategory에 추가하고equip_slot_limits에 BACKGROUND(동시 장착 1개) 시딩.ItemMasterDataSeeder가 코드로 조회해 없으면 INSERT, 정의가 다르면 UPDATE, 정의 목록에 없는 활성 아이템은 비활성화(RewardMasterDataSeeder.seedBadges와 같은 패턴). 기본 보유 7종(탐험가 모자 / 보라 선글라스 / 빨간 스카프 / 노란 우비 / 탐험 조끼 / 여행 가방 / 탐험 돋보기, 가격 0,is_default=true) + 배경 5종(포근한 카페 320 / 햇살 교실 320 / 포근한 방 280 / 바닷가 캠핑 360 / 별빛 관측소 280). 구 아이템(SUNGLASSES,BLUE_SCARF, 판매 모자 3종)은 비활성화되고 행은 남습니다.GET /api/shop/items는is_active=true AND is_default=false만 반환 → 배경 5종만 노출.DefaultItemGranter가 보유 목록(GET /api/users/me/items)·퀘스티(GET /api/users/me/questy)·장착(POST /api/users/me/items/{id}/equip) 진입 시 미보유 기본 아이템을INSERT ... SELECT ... WHERE NOT EXISTS ... ON DUPLICATE KEY UPDATE로 멱등 지급. 가격 0이라 포인트 원장·활동 기록은 남기지 않습니다. 가입 훅(회원 도메인)은 건드리지 않았습니다.변경 사항
ShopItemResponseDTO.isDefault는 상점 목록에서 항상 false).readOnly해제).category컬럼(VARCHAR 20)에BACKGROUND값이 들어가고equip_slot_limits에 행 1개가 시더로 추가됨. 기존 dev DB는 재부팅만으로 반영(시더가 upsert + 비활성화).image_url은 전부 null 유지. 프론트가 상점 응답의code로 자체 에셋을 매핑합니다.docs/error-codes.md변경 없음.ShopItemController/UserItemController/QuestyController설명에 기본 아이템 제외·지급 시점 명시.스크린샷 (Swagger 등)
경로 추가·변경이 없어
SwaggerGroupCoverageTest그대로 통과. 통합 테스트에서GET /api/shop/items결과가 배경 5종(COZY_CAFE,SUNNY_CLASSROOM,COZY_ROOM,BEACH_CAMPING,STARLIGHT_OBSERVATORY)만인 것을 확인했습니다.💬 리뷰 요구사항
UserItemRepository.grantDefaultItems:INSERT ... SELECT에서ON DUPLICATE KEY UPDATE id = id가 "Column 'id' in field list is ambiguous"로 실패해user_items.id = user_items.id로 한정했습니다. 또NOT EXISTS로 이미 보유한 행을 SELECT 단계에서 걸러, 전부 보유한 정상 상태에서 홈 조회마다 기존 행에 X-lock을 잡지 않게 했습니다(ON DUPLICATE KEY는 동시 첫 요청 경합의 안전망으로만 남김).DefaultItemGranter)에 두되 트랜잭션은 호출부에 합류(REQUIRED)합니다. 지급과 이어지는 조회가 어긋날 이유가 없어 REQUIRES_NEW를 쓰지 않았습니다.POST /api/shop/items/{id}/purchase로 0원 "구매"가 가능합니다(이미 보유면 400). 프론트가 쓰지 않는 경로라 그대로 뒀는데, 막는 게 낫다고 보시면findByIdAndIsActiveTrueAndIsDefaultFalse한 줄로 닫을 수 있습니다.ShopItem.deactivate()는user_items.is_equipped를 건드리지 않습니다. 비활성 아이템을 나중에 정의에 되살리면 장착 상태로 다시 나타날 수 있어 주석으로 남겼습니다(현재는 dev 데이터뿐).PR 전 필수 체크리스트
테스트 결과
ItemMasterDataSeederTest(INSERT / no-op / UPDATE / 비활성화·재활성화),ShopItemServiceTest,UserItemServiceTest(지급이 조회보다 먼저 호출되는지 InOrder 검증)updated_at불변. 구매 통합 테스트는 비활성화된GOLDEN_CROWN대신COZY_CAFE(320P) 기준으로 변경SwaggerGroupCoverageTest통과DB_URL없이 도는contextLoads1건만 실패(환경 문제, CI는 MySQL 서비스 컨테이너 사용)🤖 Generated with Claude Code
https://claude.ai/code/session_01HtgegmjNs3gAc6qNCTekNa