Skip to content

[feat] 데이트 코스 수정 및 삭제 기능 구현#6

Merged
1000hyehyang merged 4 commits into
devfrom
feat/5-datecourse_edit_delete
Jun 6, 2026
Merged

[feat] 데이트 코스 수정 및 삭제 기능 구현#6
1000hyehyang merged 4 commits into
devfrom
feat/5-datecourse_edit_delete

Conversation

@HHS-kor

@HHS-kor HHS-kor commented Jun 5, 2026

Copy link
Copy Markdown
Member

✨ 무엇을 바꿨나요?

저장된 데이트 코스를 수정하고 삭제할 수 있는 API를 추가함,
(수정 API에서 발생하던 500 오류도 함께 수정)

🔗 관련 이슈

Closes #5

💡 왜 바꿨나요?

데이트 코스 생성·저장까지만 가능했던 상태에서, 저장 이후 코스 내용을 바꾸거나 삭제할 수 없어 실사용에 제약 있음.
코스 이름 변경, 장소 추가·제거·순서 변경을 한 번의 요청으로 처리하는 수정기능과, soft delete 기반의 삭제 기능을 구현함.

📝 주요 변경 사항

  • PUT /api/v1/rooms/{roomId}/date-courses/{dateCourseId} — 코스 수정 API 추가
    • 코스 이름, 장소 구성(순서 포함) 전체 교체 방식으로 처리
    • 수정 결과가 같은 방의 다른 저장 코스와 동일한 장소 구성·순서이면 409 반환
    • 코스 생성자 또는 저장자만 수정 가능 (그 외 403)
  • DELETE /api/v1/rooms/{roomId}/date-courses/{dateCourseId} — 코스 삭제 API 추가
    • Soft delete 방식으로 처리 → 삭제 후 동일한 장소 조합으로 신규 코스 재생성 가능
    • 코스 생성자 또는 저장자만 삭제 가능 (그 외 403)
  • DateCourse.clearSkippedSlots() — 수동 편집 후 skippedSlotIndices를 비워 생성 시점 정보와의 불일치를 방지
  • RoomPlaceRepository.findAllByIdInAndRoomId JOIN FETCH 추가 — 수정 API 500 버그 수정
    • deleteByDateCourseId의 @Modifying(clearAutomatically = true) 실행 후 JPA 영속성 컨텍스트가 초기화되어 RoomPlace 엔티티가 detached 상태가 됨
    • 이후 toCourseResult에서 place / serviceCategory / serviceTag를 lazy 로드하면 LazyInitializationException 발생 → 500
    • 기존 단건 조회(findByIdAndRoomId)와 동일하게 join fetch로 연관 엔티티를 즉시 로드하도록 수정
  • scripts/seed-datecourse-test.sql — 로컬 Swagger 테스트용 Mock 데이터 시드 추가 (장소 27개, POPULAR 테스트용 likes 포함)

👀 리뷰어가 보면 좋은 부분

  • DateCourseEditService의 장소 전체 교체 방식: 부분 교체(diff 방식) 대신 기존 DateCoursePlace를 전부 삭제 후 재삽입date_course_places의 uq_date_course_places_course_order(date_course_id, sequence_order 유니크) 제약 때문에 in-place 업데이트 시 순서가 충돌할 수 있어 이 방식을 선택
  • 중복 코스 검사 범위: existsSavedCourseWithSameRoomPlacesExcluding으로 자기 자신은 제외하고 다른 저장 코스와의 중복만 검사함. (자기 자신의 이전 구성과 동일하게 되돌리는 수정은 허용)
  • 500 버그 관련: clearAutomatically = true는 flush 후 컨텍스트를 비우므로, rename/clearSkippedSlots의 dirty 변경은 정상 반영됨. 문제는 flush 이후 detached된 RoomPlace의 lazy 프록시 접근임. findByIdAndRoomId(단건)은 이미 join fetch가 있었는데 배치 조회(findAllByIdInAndRoomId)만 누락된 것이 원인이었음.

🧪 테스트

방식 (해당하는 것만 체크)

  • 로컬 환경에서 확인
  • 운영 환경에서 확인
  • 단위 / 통합 테스트
  • 해당 없음

메모 (시나리오, 커맨드, 스크린샷 링크 등 — 선택)

  • scripts/seed-datecourse-test.sql로 장소 27개(FOOD 10·CAFE 9·ACTIVITY 8)를 시드한 뒤 Swagger UI에서 전체 워크플로 검증
  • 검증 시나리오: 시/도·시/군/구 필터 조회 → 3슬롯 코스 생성(GENERAL/TRENDY/POPULAR) → 저장 → 목록·상세 조회 → 수정(3개·5개·순서 변경) → 중복 수정 409 → 삭제 후 404 → soft delete 후 동일 조합 재생성 → 내 코스 조회
  • 단위 테스트: DateCourseEditServiceTest, DateCourseDeleteServiceTest, DateCourseDuplicatePolicyTest, DateCourseUpdateRequestValidationTest 추가

HHS-kor and others added 2 commits June 4, 2026 13:31
[주의] 단위 테스트(gradle test)는 통과하였으나, 로컬 서버를 직접 구동하여
API 호출로 검증하는 통합 테스트는 아직 수행하지 않은 상태입니다.

변경 사항:
- PUT /api/v1/rooms/{roomId}/date-courses/{dateCourseId}
  코스 이름·장소 순서·삭제·추가를 단일 전체 교체 방식으로 처리.
  추가 장소는 해당 방에 저장된 roomPlaceId만 허용(방 소속 검증).
  중복 코스 발생 시 E409_DUPLICATE_DATE_COURSE 코드로 응답하여
  프론트에서 모달 분기 가능하도록 함.
  권한: 코스 생성자 또는 저장자만 수정 가능.

- DELETE /api/v1/rooms/{roomId}/date-courses/{dateCourseId}
  저장된 코스를 soft delete(deletedAt 설정).
  삭제 후 목록·상세·중복 판정 모든 조회에서 자동 제외.
  권한: 코스 생성자 또는 저장자만 삭제 가능.

기타:
- DateCourse → SoftDeletableEntity 상속으로 변경
- 기존 저장/조회 쿼리에 deletedAt IS NULL 조건 추가
- E409_DUPLICATE_DATE_COURSE ErrorCode 추가
  (기존 DateCourseSaveService의 중복 409도 통일)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- RoomPlaceRepository.findAllByIdInAndRoomId에 JOIN FETCH 추가
  deleteByDateCourseId의 clearAutomatically=true 실행 후 영속성 컨텍스트가
  초기화되어 RoomPlace 엔티티가 detached 상태가 됨
  이후 toCourseResult에서 place/serviceCategory/serviceTag를 lazy 로드하면
  LazyInitializationException이 발생해 500 응답을 반환하던 버그 수정
- scripts/seed-datecourse-test.sql 추가
  데이트 코스 전체 워크플로(생성·저장·수정·삭제) 로컬 테스트용
  장소 27개(FOOD 10, CAFE 9, ACTIVITY 8), POPULAR 테스트용 likes 포함

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@HHS-kor HHS-kor requested a review from 1000hyehyang June 5, 2026 17:25
HHS-kor and others added 2 commits June 6, 2026 02:36
- DateCourseEditService: 미사용 import(LinkedHashMap) 제거
- 테스트 메서드명을 checkstyle MethodName 규칙(^[a-z][a-zA-Z0-9]*$)에 맞게 영어 camelCase로 변경
  DateCourseUpdateRequestValidationTest, DateCourseEditServiceTest,
  DateCourseDeleteServiceTest, DateCourseDuplicatePolicyTest

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@1000hyehyang 1000hyehyang merged commit 4abb316 into dev Jun 6, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] 데이트 코스 수정 및 삭제 기능 구현

2 participants