개요
명지도 장소 리뷰 기능의 데이터 계층입니다. 리뷰 본문 + 키워드 태그 + 사진/영상 미디어 + 좋아요를 저장합니다.
작업 내용
Review 엔티티: uuid(공개키), pin(FK), author(FK), content(≤400), likeCount(비정규화), hidden(자동숨김), keywords(@ElementCollection), media(@OneToMany)
ReviewMedia 엔티티: url, mediaType(IMAGE/VIDEO), sortOrder (리뷰당 ≤10, 순서 보존)
ReviewLike 엔티티: (member, review) 유니크 제약
ReviewKeyword enum: 3그룹 × 6 + NONE_APPROPRIATE (code/emoji/label/fbOnly)
ReviewKeywordGroup, ReviewMediaType enum
ReviewRepository: findByUuid(author+media fetch), 장소별 최신순 페이지(hidden 제외 + 차단 제외 변형), 좋아요 원자적 증감, 운영자 큐(findByHiddenTrue)
ReviewLikeRepository: 토글/중복판정/isLiked 일괄조회
설계 결정
- 소프트삭제 없음(하드삭제 + S3 미디어 정리)
- 좋아요 수는 리포지토리 원자적 증감으로만 변경(
@Setter 금지)
- 상세 조회 시 media(List)+keywords(Set) 동시 fetch는 카테시안 곱 → keywords는 lazy 분리
검증
ReviewRepositoryIT (Testcontainers Postgres): 키워드/미디어 순서 round-trip, 최신순 정렬, 차단 제외, 자동숨김 제외, 좋아요 원자증감(0 하한), 중복좋아요 제약, isLiked 일괄조회
관련 파일
domain/thingo/review/entity/**, domain/thingo/review/repository/**, test/.../review/repository/ReviewRepositoryIT.java
개요
명지도 장소 리뷰 기능의 데이터 계층입니다. 리뷰 본문 + 키워드 태그 + 사진/영상 미디어 + 좋아요를 저장합니다.
작업 내용
Review엔티티: uuid(공개키), pin(FK), author(FK), content(≤400), likeCount(비정규화), hidden(자동숨김), keywords(@ElementCollection), media(@OneToMany)ReviewMedia엔티티: url, mediaType(IMAGE/VIDEO), sortOrder (리뷰당 ≤10, 순서 보존)ReviewLike엔티티: (member, review) 유니크 제약ReviewKeywordenum: 3그룹 × 6 +NONE_APPROPRIATE(code/emoji/label/fbOnly)ReviewKeywordGroup,ReviewMediaTypeenumReviewRepository: findByUuid(author+media fetch), 장소별 최신순 페이지(hidden 제외 + 차단 제외 변형), 좋아요 원자적 증감, 운영자 큐(findByHiddenTrue)ReviewLikeRepository: 토글/중복판정/isLiked 일괄조회설계 결정
@Setter금지)검증
ReviewRepositoryIT(Testcontainers Postgres): 키워드/미디어 순서 round-trip, 최신순 정렬, 차단 제외, 자동숨김 제외, 좋아요 원자증감(0 하한), 중복좋아요 제약, isLiked 일괄조회관련 파일
domain/thingo/review/entity/**,domain/thingo/review/repository/**,test/.../review/repository/ReviewRepositoryIT.java