Skip to content

Comments

[Release] merge to main#112

Merged
jiminnimij merged 7 commits intomainfrom
develop
Feb 8, 2026
Merged

[Release] merge to main#112
jiminnimij merged 7 commits intomainfrom
develop

Conversation

@jiminnimij
Copy link
Member

#️⃣ 연관된 이슈

관련된 이슈 번호를 적어주세요. 예: #이슈번호

#️⃣ 작업 내용

이번 PR에서 작업한 내용을 간략히 설명해주세요. (이미지 첨부 가능)

#️⃣ 테스트 결과

코드 변경에 대해 테스트를 수행한 결과를 요약해주세요. 예: 모든 테스트 통과 여부, 새로 작성한 테스트 케이스 등

#️⃣ 변경 사항 체크리스트

  • 코드에 영향이 있는 모든 부분에 대한 테스트를 작성하고 실행했나요?
  • 문서를 작성하거나 수정했나요? (필요한 경우)
  • 코드 컨벤션에 따라 코드를 작성했나요?
  • 본 PR에서 발생할 수 있는 모든 의존성 문제가 해결되었나요?

#️⃣ 스크린샷 (선택)

관련된 스크린샷이 있다면 여기에 첨부해주세요.

#️⃣ 리뷰 요구사항 (선택)

리뷰어가 특별히 봐주었으면 하는 부분이 있다면 작성해주세요.
예시: 이 부분의 코드가 잘 작동하는지 테스트해 주실 수 있나요?

📎 참고 자료 (선택)

관련 문서, 스크린샷, 또는 예시 등이 있다면 여기에 첨부해주세요

@jiminnimij jiminnimij self-assigned this Feb 8, 2026
@jiminnimij jiminnimij added ☕BE 🚀Deploy 배포 관련 labels Feb 8, 2026
@jiminnimij jiminnimij merged commit 42ff7e8 into main Feb 8, 2026
@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @jiminnimij, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request implements a significant refactoring of how exhibition viewing and reviewing statuses are managed. By introducing a new 'View' domain, the system now clearly separates the concept of a 'viewed' exhibition from a 'scrapped' one. This change simplifies the 'Scrap' entity, making it more focused, and allows for dynamic determination of 'viewed' and 'reviewed' statuses based on the new 'View' entity and existing review posts. The refactoring enhances modularity, improves data integrity, and provides a more robust foundation for future feature development.

Highlights

  • New 'View' Feature Introduction: A dedicated 'View' entity, repository, service, and controller have been introduced to manage exhibitions that a user has viewed, separating this concern from the 'Scrap' functionality.
  • Scrap Entity Refactoring: The 'Scrap' entity has been streamlined by removing the 'isViewed' and 'isReviewed' flags. Its sole responsibility is now to track user-scrapped exhibitions.
  • Dynamic Status Derivation: The 'isViewed' status for scrapped items is now dynamically determined by checking for a corresponding 'View' record. Similarly, 'isReviewed' status for viewed items is derived by checking for existing 'REVIEW' posts.
  • API Endpoint Changes: Existing 'markViewed' and 'getViewedScraps' endpoints have been removed from 'ScrapController'. New API endpoints for adding, removing, and listing views have been added to the new 'ViewController'.
  • Post Deletion Logic Update: When a 'REVIEW' type post is deleted, the system now correctly removes the associated 'View' record, ensuring data consistency.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • src/main/java/com/example/tikitaka/domain/post/service/PostService.java
    • Imported and injected ViewService.
    • Removed the call to scrapService.markReviewed.
    • Added a call to viewService.removeView when a REVIEW post is deleted.
  • src/main/java/com/example/tikitaka/domain/post/service/ReviewService.java
    • Imported and injected ViewRepository and ViewService.
    • Modified addReview to conditionally add a View record via viewService if one does not already exist, replacing the previous scrapService.markReviewed call.
  • src/main/java/com/example/tikitaka/domain/scrap/ViewErrorCode.java
    • Added new enum defining error codes for View operations (e.g., ALREADE_EXIST_VIEW, NOT_FOUND_VIEW).
  • src/main/java/com/example/tikitaka/domain/scrap/controller/ScrapController.java
    • Removed markViewed (PATCH) and getViewedScraps (GET) API endpoints.
  • src/main/java/com/example/tikitaka/domain/scrap/controller/ViewController.java
    • Added new REST controller for managing View entities.
    • Introduced POST /views/{exhibitionId} for adding a view.
    • Introduced DELETE /views/{exhibitionId} for removing a view.
    • Introduced GET /views for retrieving a paginated list of viewed exhibitions.
  • src/main/java/com/example/tikitaka/domain/scrap/dto/ScrapListItemDto.java
    • Removed the isReviewed field.
    • Updated the from static method to accept isViewed as a parameter.
  • src/main/java/com/example/tikitaka/domain/scrap/dto/ViewsDto.java
    • Added new DTO for representing viewed exhibitions, including isReviewed status.
  • src/main/java/com/example/tikitaka/domain/scrap/dto/response/ViewsResponseDto.java
    • Added new response DTO for paginated lists of ViewsDto.
  • src/main/java/com/example/tikitaka/domain/scrap/entity/Scrap.java
    • Removed isViewed and isReviewed fields.
    • Removed setViewed and updateReview methods.
  • src/main/java/com/example/tikitaka/domain/scrap/repository/ScrapRepository.java
    • Updated findPageByMemberIdOrderByEndDateAndViewed to findPageByMemberId.
    • Rewrote the query to return ScrapListItemDto directly, incorporating a LEFT JOIN with View to determine isViewed status.
    • Removed findPageByMember_MemberIdAndIsViewed method.
  • src/main/java/com/example/tikitaka/domain/scrap/repository/ViewRepository.java
    • Added new JPA repository for the View entity.
    • Included methods for checking existence, finding by member and exhibition, and a paginated query to retrieve ViewsDto with derived isReviewed status.
  • src/main/java/com/example/tikitaka/domain/scrap/service/ScrapService.java
    • Imported and injected ViewRepository, MemberValidator, and ExhibitionValidator.
    • Updated findScrapList to use the new ScrapRepository query.
    • Removed isViewed and isReviewed initialization during Scrap creation.
    • Removed markViewed, findScrapListByViewed, and markReviewed methods.
  • src/main/java/com/example/tikitaka/domain/scrap/service/ViewService.java
    • Added new service for managing View entities.
    • Implemented addView, addViewByReview, removeView, and findViewList methods.
  • src/main/java/com/example/tikitaka/domain/view/entity/View.java
    • Renamed file and moved View entity to the domain.scrap package.
  • src/test/java/com/example/tikitaka/domain/scrap/controller/ScrapControllerTest.java
    • Removed tests related to markViewed functionality.
  • src/test/java/com/example/tikitaka/domain/scrap/repository/ScrapRepositoryTest.java
    • Updated saveEx to use cheerCount instead of cheeringCount.
    • Adjusted saveScrap to reflect Scrap entity changes (no isViewed, isReviewed).
    • Updated findPageByMemberIdOrderByEndDateAndViewed to findPageByMemberId and adjusted assertions for ScrapListItemDto.
  • src/test/java/com/example/tikitaka/domain/scrap/service/ScrapServiceTest.java
    • Updated findPageByMemberIdOrderByEndDateAndViewed mock to findPageByMemberId and adjusted return type.
    • Removed isViewed assertion in addScrap test.
    • Removed tests related to markViewed functionality.
Activity
  • The pull request was opened by jiminnimij with the title "[Release] merge to main", indicating a merge of a release branch into the main development line.
  • The description provided is a standard template, suggesting that the detailed changes are to be inferred from the code diffs.
  • No explicit comments, reviews, or other human activities are available in the provided context.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

이번 PR은 '관람(view)' 기능을 '스크랩(scrap)' 기능에서 분리하는 리팩토링을 중심으로 진행되었습니다. 전반적으로 기능 분리가 잘 이루어졌으며, 이에 따라 관련 컨트롤러, 서비스, 리포지토리, DTO가 깔끔하게 정리되었습니다. 몇 가지 코드 개선점을 제안 드립니다. ViewErrorCode의 오타 수정, PostService의 분기문 개선, ViewService의 중복 코드 제거, 그리고 테스트 코드의 오류 수정이 필요해 보입니다. 자세한 내용은 각 파일의 리뷰 코멘트를 확인해주세요.

Comment on lines 31 to 40
if (post.getPostType() == PostType.REVIEW) {
scrapService.markReviewed(memberId, post.getExhibition().getExhibitionId()); // TODO: N+1 문제 해결
post.getExhibition().decreaseReviewCount();
viewService.removeView(memberId, post.getExhibition().getExhibitionId());
}
if (post.getPostType() == PostType.CHEER) {
post.getExhibition().decreaseCheerCount();
}
if (post.getPostType() == PostType.QUESTION) {
post.getExhibition().decreaseQuestionCount();
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

PostType enum 값에 따라 분기 처리를 위해 여러 if 문을 사용하고 있습니다. 이 경우 switch 문을 사용하면 코드가 더 명확해지고 가독성이 향상됩니다.

        switch (post.getPostType()) {
            case REVIEW -> {
                post.getExhibition().decreaseReviewCount();
                viewService.removeView(memberId, post.getExhibition().getExhibitionId());
            }
            case CHEER -> post.getExhibition().decreaseCheerCount();
            case QUESTION -> post.getExhibition().decreaseQuestionCount();
        }

@Getter
@AllArgsConstructor
public enum ViewErrorCode implements BaseErrorCode {
ALREADE_EXIST_VIEW(HttpStatus.CONFLICT, "VIEW_409_1", "이미 관람한 내역입니다."),
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Enum 이름에 오타가 있습니다. ALREADE_EXIST_VIEWALREADY_EXIST_VIEW가 되어야 합니다.

Suggested change
ALREADE_EXIST_VIEW(HttpStatus.CONFLICT, "VIEW_409_1", "이미 관람한 내역입니다."),
ALREADY_EXIST_VIEW(HttpStatus.CONFLICT, "VIEW_409_1", "이미 관람한 내역입니다."),

Comment on lines +34 to +62
public void addView(Long memberId, Long exhibitionId) {
Member member = memberValidator.validateMember(memberId);
Exhibition exhibition = exhibitionValidator.validateExhibition(exhibitionId);

if (viewRepository.existsByMemberAndExhibition(member, exhibition)) {
throw new BaseErrorException(ViewErrorCode.ALREADE_EXIST_VIEW);
}

View view = View.builder()
.member(member)
.exhibition(exhibition)
.build();

viewRepository.save(view);
}

@Transactional
public void addViewByReview(Member member, Exhibition exhibition) {
if (viewRepository.existsByMemberAndExhibition(member, exhibition)) {
throw new BaseErrorException(ViewErrorCode.ALREADE_EXIST_VIEW);
}

View view = View.builder()
.member(member)
.exhibition(exhibition)
.build();

viewRepository.save(view);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

addViewaddViewByReview 메서드에 중복된 코드가 많습니다. 관람 내역이 이미 존재하는지 확인하고, 없으면 생성하여 저장하는 로직이 동일합니다. 이 부분을 별도의 private 메서드로 추출하여 중복을 제거하는 것이 좋습니다.

    @Transactional
    public void addView(Long memberId, Long exhibitionId) {
        Member member = memberValidator.validateMember(memberId);
        Exhibition exhibition = exhibitionValidator.validateExhibition(exhibitionId);
        createViewIfNotExists(member, exhibition);
    }

    @Transactional
    public void addViewByReview(Member member, Exhibition exhibition) {
        createViewIfNotExists(member, exhibition);
    }

    private void createViewIfNotExists(Member member, Exhibition exhibition) {
        if (viewRepository.existsByMemberAndExhibition(member, exhibition)) {
            throw new BaseErrorException(ViewErrorCode.ALREADE_EXIST_VIEW);
        }

        View view = View.builder()
                .member(member)
                .exhibition(exhibition)
                .build();

        viewRepository.save(view);
    }

Comment on lines +43 to +44
ScrapListItemDto dto1 = ScrapListItemDto.from(s1, true);
ScrapListItemDto dto2 = ScrapListItemDto.from(s2, true);
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

테스트 데이터 설정이 이후의 검증 코드와 일치하지 않습니다. dto1isViewed=true로 생성했지만, 59행의 assertThat(item0.isViewed()).isFalse() 검증으로 인해 테스트가 실패할 것입니다. 검증 코드에 맞게 테스트 데이터를 수정해야 합니다.

Suggested change
ScrapListItemDto dto1 = ScrapListItemDto.from(s1, true);
ScrapListItemDto dto2 = ScrapListItemDto.from(s2, true);
ScrapListItemDto dto1 = ScrapListItemDto.from(s1, false);
ScrapListItemDto dto2 = ScrapListItemDto.from(s2, true);

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

Labels

☕BE 🚀Deploy 배포 관련

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant