Skip to content

Conversation

@leegwichan
Copy link
Member

@leegwichan leegwichan commented Jul 15, 2025

✨ 개요

  • 기획 변경에 따른 ERD 수정

🧾 관련 이슈

closed #75

🔍 참고 사항 (선택)

리뷰 요구 사항

  • 제거된 코드가 많아 커밋별로 리뷰하시는 걸 추천드립니다.
  • 개편한 ERD에 맞춰 Entity를 만들었습니다. 시간이 되신다면 누락된 점이 없는지 확인 부탁드립니다.

작업 내용

  • 사용하지 않는 도메인은 모두 제거하였습니다.
  • 개편한 ERD에 맞춰 Entity를 만들었습니다.
    • Store 는 Kakao API에서 받는 데이터를 그대로 넣기 때문에, 따로 유효성 검사를 추가하지 않았습니다.
    • Article 은 어드민이 직접 DB에 넣어주기 때문에, 따로 유효성 검사를 추가하지 않았습니다.
  • 개편한 ERD에 맞추어 flyway 관련 SQL 파일을 수정했습니다. 머지 전 DB 초기화 실시하도록 하겠습니다.

Summary by CodeRabbit

  • 신규 기능

    • Cheer(응원) 및 Article(기사) 도메인 엔터티가 추가되었습니다.
    • AuditingEntity를 기반으로 Member, Store에 생성일(createdAt) 필드가 추가되었습니다.
  • 리팩터링

    • Store 엔터티가 단순화되고 빌더 패턴이 적용되었습니다.
    • StoreCategory의 패키지가 변경되었습니다.
  • 버그 수정

    • Cheer 생성 시 설명 및 이미지 키의 유효성 검사가 추가되었습니다.
  • 데이터베이스

    • 스키마가 전면 개편되어 member, store, cheer, article 테이블로 변경되었습니다.
    • 초기/개발용 데이터가 새로운 스키마에 맞게 갱신되었습니다.
  • 테스트

    • Cheer 엔터티에 대한 테스트가 추가되었습니다.
    • 기존 Store, Menu, Bookmark 등 관련 테스트가 삭제되었습니다.

@coderabbitai
Copy link

coderabbitai bot commented Jul 15, 2025

"""

Walkthrough

ERD 변경에 따라 도메인 엔티티, DB 마이그레이션, 시드 데이터, 예외 코드, 테스트 코드가 대폭 수정되었습니다. 메뉴, 북마크, 가격, 할인, 관심지역 등 기존 도메인 및 관련 테스트가 삭제되고, Article, Cheer 등 신규 엔티티 및 DB 테이블이 도입되었으며, Store와 Member 구조가 재정의되었습니다.

Changes

파일/그룹 변경 요약
src/main/java/eatda/domain/menu/Discount.java, Menu.java, Price.java
src/main/java/eatda/domain/store/StoreHours.java, StorePhoneNumber.java
src/main/java/eatda/domain/bookmark/Bookmark.java
src/main/java/eatda/enums/InterestArea.java
메뉴, 할인, 가격, 북마크, 관심지역, 영업시간, 매장전화번호 등 도메인 및 값 객체/열거형 삭제
src/main/java/eatda/domain/store/Store.java Store 엔티티 구조 대폭 변경: 필드/생성자/밸리데이션/임베디드 제거, Builder 패턴 도입, kakaoId 등 신규 필드 추가, 주소 필드 분리, createdAt 추가
src/main/java/eatda/domain/member/Member.java AuditingEntity 상속으로 createdAt 필드 추가
src/main/java/eatda/domain/article/Article.java Article JPA 엔티티 신규 생성
src/main/java/eatda/domain/store/Cheer.java Cheer JPA 엔티티 신규 생성, 입력값 검증 로직 포함
src/main/java/eatda/domain/store/StoreCategory.java
src/test/java/eatda/domain/store/StoreCategoryTest.java
StoreCategory 패키지 변경 (eatda.enums → eatda.domain.store)
src/main/java/eatda/exception/BusinessErrorCode.java Store, Menu, Bookmark 관련 에러코드 삭제, Cheer 관련 에러코드 추가
src/main/resources/db/migration/V1__init.sql ERD 전면 개편: 테이블명/스키마/관계/제약조건 변경, article, cheer, member, store 테이블 신규 정의
src/main/resources/db/seed/dev/V2__dev_init_data.sql
src/main/resources/db/seed/local/V2__local_init_data.sql
시드 데이터 전면 교체: menu/bookmark 삭제, article/cheer 추가, member/store 데이터 및 스키마 변경
src/test/java/eatda/domain/bookmark/BookmarkTest.java
src/test/java/eatda/domain/menu/DiscountTest.java, MenuTest.java, PriceTest.java
src/test/java/eatda/domain/store/StoreTest.java, StoreHoursTest.java, StorePhoneNumberTest.java
src/test/java/eatda/enums/InterestAreaTest.java
삭제: 메뉴, 북마크, 가격, 할인, 관심지역, 매장 관련 테스트 코드 일괄 제거
src/test/java/eatda/domain/store/CheerTest.java Cheer 엔티티에 대한 신규 단위 테스트 추가
src/main/java/eatda/domain/AuditingEntity.java AuditingEntity 추상 클래스 신규 생성, createdAt 필드 및 생성 시점 자동 설정 기능 포함

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Member
    participant Store
    participant Cheer
    participant Article

    User->>Member: 회원 가입/조회
    User->>Store: 매장 조회
    User->>Cheer: 매장에 Cheer 등록/조회
    User->>Article: 기사(Article) 조회
    Cheer->>Member: 회원 참조
    Cheer->>Store: 매장 참조
Loading

Assessment against linked issues

Objective Addressed Explanation
ERD 수정 및 엔티티 구조 변경 (#75)
기존 도메인(메뉴, 북마크 등) 제거 및 신규 도메인(Article, Cheer 등) 도입 (#75)
DB 마이그레이션 및 시드 데이터 ERD에 맞게 변경 (#75)
예외 코드 및 테스트 코드 ERD 변경에 맞게 수정/삭제 (#75)

Suggested labels

feat

Poem

ERD가 바뀌었어요, 🐇
메뉴와 북마크는 안녕~
기사와 응원이 새로 왔죠,
토끼가 깡총 뛰며 환호해요!
새 엔티티로 반짝반짝,
데이터도 새롭게 피었어요.
🥕✨🐰
"""

✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions
Copy link

📄 Terraform Plan Summary

🛡️ Common Infrastructure


No plan summary

Status: ✅ No Changes


🛠️ Development Environment


No plan summary

Status: ✅ No Changes


📋 Full Results: View in Actions

@github-actions
Copy link

📌 최신 ERD가 자동 생성되었습니다.

👉 ERD 보러가기

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 7

🔭 Outside diff range comments (1)
src/main/java/eatda/domain/member/Member.java (1)

70-75: 생성자에서 createdAt 필드가 설정되지 않는 문제가 있습니다.

세 번째 생성자에서는 createdAt 필드가 설정되지 않아 null 상태로 남게 됩니다. 이는 @Column(nullable = false) 설정과 충돌하여 데이터베이스 제약 조건 위반을 초래할 수 있습니다.

다음과 같이 수정하세요:

 public Member(String nickname, String mobilePhoneNumber, boolean optInMarketing) {
     validateOptInMarketing(optInMarketing);
     this.nickname = nickname;
     this.mobilePhoneNumber = new MobilePhoneNumber(mobilePhoneNumber);
     this.optInMarketing = optInMarketing;
+    this.createdAt = LocalDateTime.now();
 }
♻️ Duplicate comments (2)
src/main/resources/db/seed/local/V2__local_init_data.sql (1)

11-17: Store 데이터의 일관성 문제가 있습니다.

dev 환경 seed 데이터와 동일한 문제가 있습니다. name과 category가 일치하지 않고, 모든 store가 동일한 place_url을 사용하고 있습니다.

src/main/java/eatda/domain/store/Store.java (1)

53-54: createdAt 필드 처리 방식을 개선하세요.

Cheer 엔티티와 동일하게 @CreationTimestamp 사용을 권장합니다.

Also applies to: 74-74

🧹 Nitpick comments (5)
src/test/java/eatda/domain/store/StoreCategoryTest.java (1)

14-31: 테스트 커버리지를 개선할 수 있습니다.

현재 from() 메서드만 테스트되고 있습니다. isValid() 메서드와 모든 enum 값에 대한 테스트를 추가하는 것을 고려해보세요.

다음과 같은 테스트 추가를 고려해보세요:

@Nested
@DisplayName("isValid 메서드 테스트")
class IsValidMethod {
    
    @Test
    void 유효한_이름이면_true를_반환한다() {
        assertThat(StoreCategory.isValid("한식")).isTrue();
        assertThat(StoreCategory.isValid("양식")).isTrue();
    }
    
    @Test
    void 유효하지_않은_이름이면_false를_반환한다() {
        assertThat(StoreCategory.isValid("없는카테고리")).isFalse();
        assertThat(StoreCategory.isValid(null)).isFalse();
    }
}

@Test
void 모든_카테고리가_정상적으로_변환된다() {
    Arrays.stream(StoreCategory.values())
        .forEach(category -> 
            assertThat(StoreCategory.from(category.getCategoryName()))
                .isEqualTo(category));
}
src/main/java/eatda/domain/store/Cheer.java (1)

47-48: createdAt 필드는 JPA 어노테이션을 사용하는 것이 좋습니다.

생성자에서 직접 설정하는 대신 @CreationTimestamp 또는 @PrePersist를 사용하면 테스트가 용이하고 일관성이 향상됩니다.

+import org.hibernate.annotations.CreationTimestamp;

 @Column(name = "created_at", nullable = false)
+@CreationTimestamp
 private LocalDateTime createdAt;

그리고 생성자에서 해당 라인을 제거하세요:

-this.createdAt = LocalDateTime.now();

Also applies to: 60-60

src/main/resources/db/seed/dev/V2__dev_init_data.sql (1)

12-25: 모든 store가 동일한 place_url을 사용하고 있습니다.

각 store마다 고유한 place_url을 사용하거나, 개발용 더미 URL이라도 구분 가능하게 만드는 것이 좋습니다.

src/main/resources/db/migration/V1__init.sql (2)

7-7: 전화번호 컬럼 길이가 과도합니다.

전화번호는 국제 표기를 포함해도 20자 이내(예: +821012345678)면 충분합니다. VARCHAR(255)는 불필요하게 큰 Row 길이를 유발합니다.

-    `phone_number`     VARCHAR(255) NULL,
+    `phone_number`     VARCHAR(20)  NULL,
...
-    `phone_number`       VARCHAR(255) NOT NULL,
+    `phone_number`       VARCHAR(20)  NOT NULL,

Also applies to: 18-18


23-24: 위도·경도 DOUBLE 사용 시 부동소수 오차 가능성

지리 좌표는 DECIMAL(9,6)(1cm 단위) 정도면 충분하며, DOUBLE은 불필요한 오차와 인덱스 효율 저하가 있습니다.

-    `latitude` DOUBLE NOT NULL,
-    `longitude` DOUBLE NOT NULL,
+    `latitude`  DECIMAL(9,6) NOT NULL,
+    `longitude` DECIMAL(9,6) NOT NULL,
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 60f3d62 and d648ab6.

📒 Files selected for processing (26)
  • src/main/java/eatda/domain/article/Article.java (1 hunks)
  • src/main/java/eatda/domain/bookmark/Bookmark.java (0 hunks)
  • src/main/java/eatda/domain/member/Member.java (2 hunks)
  • src/main/java/eatda/domain/menu/Discount.java (0 hunks)
  • src/main/java/eatda/domain/menu/Menu.java (0 hunks)
  • src/main/java/eatda/domain/menu/Price.java (0 hunks)
  • src/main/java/eatda/domain/store/Cheer.java (1 hunks)
  • src/main/java/eatda/domain/store/Store.java (2 hunks)
  • src/main/java/eatda/domain/store/StoreCategory.java (1 hunks)
  • src/main/java/eatda/domain/store/StoreHours.java (0 hunks)
  • src/main/java/eatda/domain/store/StorePhoneNumber.java (0 hunks)
  • src/main/java/eatda/enums/InterestArea.java (0 hunks)
  • src/main/java/eatda/exception/BusinessErrorCode.java (1 hunks)
  • src/main/resources/db/migration/V1__init.sql (1 hunks)
  • src/main/resources/db/seed/dev/V2__dev_init_data.sql (1 hunks)
  • src/main/resources/db/seed/local/V2__local_init_data.sql (1 hunks)
  • src/test/java/eatda/domain/bookmark/BookmarkTest.java (0 hunks)
  • src/test/java/eatda/domain/menu/DiscountTest.java (0 hunks)
  • src/test/java/eatda/domain/menu/MenuTest.java (0 hunks)
  • src/test/java/eatda/domain/menu/PriceTest.java (0 hunks)
  • src/test/java/eatda/domain/store/CheerTest.java (1 hunks)
  • src/test/java/eatda/domain/store/StoreCategoryTest.java (1 hunks)
  • src/test/java/eatda/domain/store/StoreHoursTest.java (0 hunks)
  • src/test/java/eatda/domain/store/StorePhoneNumberTest.java (0 hunks)
  • src/test/java/eatda/domain/store/StoreTest.java (0 hunks)
  • src/test/java/eatda/enums/InterestAreaTest.java (0 hunks)
💤 Files with no reviewable changes (15)
  • src/test/java/eatda/enums/InterestAreaTest.java
  • src/test/java/eatda/domain/bookmark/BookmarkTest.java
  • src/test/java/eatda/domain/store/StorePhoneNumberTest.java
  • src/main/java/eatda/domain/store/StorePhoneNumber.java
  • src/main/java/eatda/domain/menu/Price.java
  • src/test/java/eatda/domain/menu/MenuTest.java
  • src/test/java/eatda/domain/menu/PriceTest.java
  • src/main/java/eatda/domain/bookmark/Bookmark.java
  • src/test/java/eatda/domain/menu/DiscountTest.java
  • src/test/java/eatda/domain/store/StoreTest.java
  • src/main/java/eatda/domain/store/StoreHours.java
  • src/test/java/eatda/domain/store/StoreHoursTest.java
  • src/main/java/eatda/enums/InterestArea.java
  • src/main/java/eatda/domain/menu/Discount.java
  • src/main/java/eatda/domain/menu/Menu.java
🧰 Additional context used
🧠 Learnings (1)
src/main/java/eatda/domain/store/Store.java (1)
Learnt from: leegwichan
PR: YAPP-Github/26th-Web-Team-1-BE#60
File: src/main/java/eatda/domain/store/Coordinates.java:23-37
Timestamp: 2025-07-09T08:05:00.393Z
Learning: In Coordinates.java domain class, the developer prefers to manage Seoul coordinate boundary constants (latitude/longitude limits) in the domain layer through public static getter methods, as these represent domain rules rather than infrastructure concerns. This approach prioritizes domain integrity over strict encapsulation.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test
🔇 Additional comments (9)
src/main/java/eatda/domain/article/Article.java (2)

39-45: 엔티티 생성자 구현이 적절합니다.

생성 시점에 createdAt을 자동으로 설정하는 구현이 올바릅니다. PR 목적에 따라 추가적인 유효성 검증 없이 단순하게 구현된 점도 적절합니다.


30-34: URL 및 이미지 키 길이 검토 결과

시드 데이터 기준으로 확인한 최대 길이:

  • article_url 최대 11자
  • image_key 최대 7자

현재 설정된 length = 511은 시드 데이터 범위에서 충분히 여유가 있습니다.
다만 실제 운영 환경의 URL 및 이미지 키 길이가 더 길어질 가능성이 있으므로, 운영 DB나 로그 등을 통해 실제 사용 길이를 검토한 후 필요 시 길이 제한을 조정해 주세요.

src/main/java/eatda/domain/store/StoreCategory.java (2)

1-1: 도메인 패키지로의 이동이 적절합니다.

StoreCategoryeatda.enums에서 eatda.domain.store로 이동한 것은 도메인 중심 구조로의 개선으로 보입니다.


28-36: from() 메서드 구현이 견고합니다.

null과 빈 문자열에 대한 검증, 그리고 적절한 비즈니스 예외 처리가 잘 구현되어 있습니다.

src/test/java/eatda/domain/store/StoreCategoryTest.java (1)

1-1: 패키지 변경이 올바르게 적용되었습니다.

StoreCategory 클래스의 패키지 변경에 맞춰 테스트 클래스의 패키지도 적절히 업데이트되었습니다.

src/main/java/eatda/domain/member/Member.java (1)

45-46: createdAt 필드 추가가 적절합니다.

멤버 생성 시점을 추적하기 위한 createdAt 필드 추가는 도메인 모델 개선에 적합합니다.

src/test/java/eatda/domain/store/CheerTest.java (2)

18-29: 테스트용 기본 인스턴스 설정이 적절합니다.

새로운 도메인 모델 구조에 맞춰 MemberStore의 기본 인스턴스가 올바르게 구성되었습니다. Store의 빌더 패턴 사용도 적절합니다.


34-42: 설명 유효성 검증 테스트가 올바르게 구현되었습니다.

null과 빈 문자열에 대한 검증 테스트가 적절히 구현되어 있고, 비즈니스 예외 코드도 정확히 확인하고 있습니다.

src/main/java/eatda/domain/store/Store.java (1)

56-75: Builder 패턴이 깔끔하게 구현되었습니다.

필수 필드들이 모두 포함되어 있고, Coordinates 객체 생성도 적절하게 처리되었습니다.

Copy link
Member

@lvalentine6 lvalentine6 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이번 PR도 고생하셨습니다. 🎉
어제 같이 논의한 ERD 구조대로 잘 반영되어 있는 것 같아요!

다만 지금은 일정상 넘어가도 될 것 같지만,
외부 API나 어드민 입력이라고 해도 예외적인 값이 들어올 수 있어서
추후에는 유효성 검토가 필요하다고 생각해요.

그리고 Sonar에서 테스트 커버리지가 기준치(80%)를 만족하지 못한다고 하던데,
유효성 검증 로직이 없다 보니 커버리지가 자연스럽게 낮게 나온 것 같아요.
이럴 경우엔 통과 기준 비율을 낮추는 게 나을지
아니면 기본적인 검증이라도 추가해서 맞추는 게 좋을지 고민이 되네요.
어떻게 생각하시나요?

this.socialId = socialId;
this.email = email;
this.nickname = nickname;
this.createdAt = LocalDateTime.now();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

여기도 @PrePersist를 사용하는게 어떨까요???

this.subtitle = subtitle;
this.articleUrl = articleUrl;
this.imageKey = imageKey;
this.createdAt = LocalDateTime.now();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[제안]

createdAt 필드는 아래처럼 @PrePersist를 활용하면 JPA 생명주기와도 맞고 테스트도 더 수월할 것 같아요!

@PrePersist
    protected void onCreate() {
        this.createdAt = LocalDateTime.now();
    }

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

좋은 아이디어라고 생각합니다.
모든 Entity마다 해당 메서드가 있는 것은 불편하다고 생각해서 AuditingEntity로 해당 부분을 분리했습니다. 확인 한 번 부탁드립니다!

@YAPP-Github YAPP-Github deleted a comment from coderabbitai bot Jul 15, 2025
- cheer 의 image_key 값의 null 허용
- cheer 의 is_admin 값의 기본 값을 false 로 설정
- 초기 삽입 데이터 이름에 맞춰 일부 수정
- id 값을 받지 않도록 함
- created_at 을 관리하는 Entity 를 추상 클래스로 분리
@github-actions
Copy link

📄 Terraform Plan Summary

🛡️ Common Infrastructure


No plan summary

Status: ✅ No Changes


🛠️ Development Environment


No plan summary

Status: ✅ No Changes


📋 Full Results: View in Actions

@github-actions
Copy link

📌 최신 ERD가 자동 생성되었습니다.

👉 ERD 보러가기

@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
79.7% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube Cloud

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (3)
src/main/resources/db/seed/local/V2__local_init_data.sql (2)

18-19: 일부 store 레코드에서 road_address가 빈 문자열로 설정되어 있습니다.

개발 환경과 동일한 문제로, Store ID 4와 7에서 road_address가 빈 문자열('')로 설정되어 있습니다. 로컬 환경에서도 일관성 있는 데이터 사용을 권장합니다.


27-34: 모든 cheer 레코드에서 동일한 image_key를 사용하고 있습니다.

개발 환경과 동일한 문제로, 모든 응원 메시지에서 'default.jpg'를 사용하고 있습니다. 로컬 개발 환경에서도 다양한 이미지 키를 사용하는 것이 좋습니다.

src/main/resources/db/migration/V1__init.sql (1)

8-8: opt_in_marketing의 NULL 허용은 3-State 버그를 유발할 수 있습니다.

마케팅 수신 동의는 명확한 true/false 값을 가져야 하며, NULL을 허용하면 "동의/비동의/미정" 3-State 로직이 생겨 서비스 및 통계 로직에 문제가 발생할 수 있습니다.

🧹 Nitpick comments (4)
src/main/java/eatda/domain/AuditingEntity.java (2)

16-19: 시간대 일관성을 위해 UTC 시간 사용을 고려하세요.

현재 LocalDateTime.now()를 사용하면 서버의 시스템 시간대를 따르게 되어 서버 환경에 따라 다른 시간이 기록될 수 있습니다. 글로벌 서비스를 고려한다면 UTC 시간 사용을 권장합니다.

-        this.createdAt = LocalDateTime.now();
+        this.createdAt = LocalDateTime.now(ZoneOffset.UTC);

추가로 import 문도 수정해야 합니다:

 import java.time.LocalDateTime;
+import java.time.ZoneOffset;

11-20: 업데이트 시간 추적 기능 추가를 고려하세요.

생성시간만 추적하고 있지만, 엔티티가 수정되었을 때의 시간도 추적하는 것이 일반적입니다. 완전한 감사 기능을 위해 updatedAt 필드와 @PreUpdate 콜백 추가를 고려해보세요.

 @Getter
 @MappedSuperclass
 public abstract class AuditingEntity {
 
     @Column(name = "created_at", nullable = false)
     private LocalDateTime createdAt;
+    
+    @Column(name = "updated_at", nullable = false)
+    private LocalDateTime updatedAt;
 
     @PrePersist
     protected void onCreate() {
         this.createdAt = LocalDateTime.now();
+        this.updatedAt = LocalDateTime.now();
+    }
+    
+    @PreUpdate
+    protected void onUpdate() {
+        this.updatedAt = LocalDateTime.now();
     }
 }
src/main/resources/db/seed/dev/V2__dev_init_data.sql (1)

27-34: 모든 cheer 레코드에서 동일한 image_key를 사용하고 있습니다.

모든 응원 메시지에서 'default.jpg'를 사용하고 있는데, 개발 환경에서도 다양한 이미지 키를 사용하여 더 현실적인 테스트 데이터를 만드는 것이 좋습니다.

-VALUES (1, 1, 1, '정말 맛있어요! 강추합니다!', 'default.jpg', true),
-       (2, 2, 2, '서비스가 훌륭해요!', 'default.jpg', true),
-       (3, 3, 3, '여기 음식이 정말 맛있어요!', 'default.jpg', true),
-       (4, 4, 4, '분위기가 너무 좋아요!', 'default.jpg', true),
-       (5, 5, 5, '디저트가 정말 맛있어요!', 'default.jpg', true),
-       (6, 6, 6, '커피가 정말 맛있어요!', 'default.jpg', false),
-       (7, 7, 7, '패스트푸드가 빠르고 맛있어요!', 'default.jpg', false);
+VALUES (1, 1, 1, '정말 맛있어요! 강추합니다!', 'cheer/korean_restaurant_1.jpg', true),
+       (2, 2, 2, '서비스가 훌륭해요!', 'cheer/western_restaurant_1.jpg', true),
+       (3, 3, 3, '여기 음식이 정말 맛있어요!', 'cheer/chinese_restaurant_1.jpg', true),
+       (4, 4, 4, '분위기가 너무 좋아요!', 'cheer/western_restaurant_2.jpg', true),
+       (5, 5, 5, '디저트가 정말 맛있어요!', 'cheer/dessert_cafe_1.jpg', true),
+       (6, 6, 6, '커피가 정말 맛있어요!', 'cheer/coffee_shop_1.jpg', false),
+       (7, 7, 7, '패스트푸드가 빠르고 맛있어요!', 'cheer/fast_food_1.jpg', false);
src/main/resources/db/migration/V1__init.sql (1)

48-49: article 테이블의 URL 필드들이 장문의 URL을 지원하지 못할 수 있습니다.

article_url이 VARCHAR(511)로 설정되어 있는데, 현대 웹에서는 쿼리 파라미터가 많은 긴 URL이 일반적입니다. URL 단축 서비스를 사용하지 않는다면 더 긴 길이를 고려해야 합니다.

-    `article_url` VARCHAR(511) NOT NULL,
+    `article_url` VARCHAR(2048) NOT NULL,
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d648ab6 and b27f9f0.

📒 Files selected for processing (9)
  • src/main/java/eatda/domain/AuditingEntity.java (1 hunks)
  • src/main/java/eatda/domain/article/Article.java (1 hunks)
  • src/main/java/eatda/domain/member/Member.java (3 hunks)
  • src/main/java/eatda/domain/store/Cheer.java (1 hunks)
  • src/main/java/eatda/domain/store/Store.java (2 hunks)
  • src/main/resources/db/migration/V1__init.sql (1 hunks)
  • src/main/resources/db/seed/dev/V2__dev_init_data.sql (1 hunks)
  • src/main/resources/db/seed/local/V2__local_init_data.sql (1 hunks)
  • src/test/java/eatda/domain/store/CheerTest.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/main/java/eatda/domain/member/Member.java
  • src/test/java/eatda/domain/store/CheerTest.java
  • src/main/java/eatda/domain/store/Store.java
  • src/main/java/eatda/domain/article/Article.java
  • src/main/java/eatda/domain/store/Cheer.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test
🔇 Additional comments (1)
src/main/resources/db/migration/V1__init.sql (1)

35-35: image_key 컬럼의 NULL 허용은 비즈니스 로직에서 지원됨을 확인했습니다.

-src/main/java/eatda/domain/store/Cheer.java
• validateImageKey(String imageKey) 메서드에서
- imageKey == null일 경우 예외 없이 통과
- imageKey가 공백만으로 이루어진 경우 BusinessErrorCode.INVALID_CHEER_IMAGE_KEY 예외 발생

  • src/test/java/eatda/domain/store/CheerTest.java
    • 공백 문자열에 대한 예외 처리를 검증하는 테스트가 존재
    • imageKey가 null일 때도 예외 없이 객체가 생성됨을 비즈니스 요구사항에 부합

→ DB 마이그레이션 스크립트(image_key VARCHAR(511) NULL)와 도메인 로직이 일치합니다.

@leegwichan leegwichan merged commit d008489 into develop Jul 15, 2025
10 of 11 checks passed
@leegwichan leegwichan deleted the fix/PRODUCT-160 branch July 15, 2025 11:22
@github-actions
Copy link

🎉 This PR is included in version 1.4.0-develop.19 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@github-actions
Copy link

🎉 This PR is included in version 1.5.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[PRODUCT-160] [Fix] 1차 스프린트 ERD 수정

3 participants