Skip to content

feat: 마이페이지 맞춤형 배너 알림 조회 API 구현#62

Merged
neibler merged 3 commits intodevelopfrom
feature/59
Jan 28, 2026
Merged

feat: 마이페이지 맞춤형 배너 알림 조회 API 구현#62
neibler merged 3 commits intodevelopfrom
feature/59

Conversation

@neibler
Copy link
Copy Markdown
Contributor

@neibler neibler commented Jan 28, 2026

🔍️ 작업 내용

  • Closes #

✨ 상세 설명

🛠️ 추후 리팩토링 및 고도화 계획

📸 스크린샷 (선택)

💬 리뷰 요구사항

Summary by CodeRabbit

  • 새로운 기능
    • 로그인한 사용자에게 개인화된 배너가 자동으로 표시됩니다.
    • 상황별 배너 3종 추가: 구매 직후 리뷰 유도, 한달 후 리뷰 유도, 매거진 홍보.
    • 주문 상태와 기존 리뷰 여부, 경과 시간에 따라 적절한 배너가 우선 순위로 선택되어 노출됩니다.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jan 28, 2026

Walkthrough

사용자별 우선순위 기반 배너 선택 기능이 추가되었습니다. 초기 리뷰 유도 → 한달 후 리뷰 유도 → 매거진 순으로 판단하는 서비스, 컨버터·DTO·Enum·컨트롤러 및 주문·리뷰 조회용 저장소 확장 메서드들이 도입되었습니다.

Changes

Cohort / File(s) 변경 요약
배너 도메인 - 컨트롤러
src/main/java/com/ongil/backend/domain/banner/controller/BannerController.java
GET /api/banner 엔드포인트 추가: 인증된 userId 주입, BannerService.getBanner 위임, DataResponse<BannerResponse>로 반환
배너 도메인 - 서비스
src/main/java/com/ongil/backend/domain/banner/service/BannerService.java
읽기전용 서비스 추가: getBanner(userId) 구현 — (1) 초기 리뷰 대상 검사, (2) 한달 후 리뷰 대상 검사(기본 5일 기준), (3) 기본 매거진 배너 생성. Order/Review 집계 조회로 N+1 회피
배너 도메인 - 변환기·DTO·타입
src/main/java/com/ongil/backend/domain/banner/converter/BannerConverter.java, src/main/java/com/ongil/backend/domain/banner/dto/response/BannerResponse.java, src/main/java/com/ongil/backend/domain/banner/enums/BannerType.java
BannerConverter 추가 (toResponse), BannerResponse 레코드 추가(필드: type, title, buttonText, targetUrl, targetId, enabled), BannerType enum 추가( MAGAZINE, REVIEW_PROMPT, MONTHLY_REVIEW_PROMPT )
주문 저장소 확장
src/main/java/com/ongil/backend/domain/order/repository/OrderRepository.java
사용자·상태·확인일자 기준의 JPQL 조회 메서드 4종 추가(범위/이후/이전/상태만) — 서비스의 주문 필터링에 사용
리뷰 저장소 - 배치 조회
src/main/java/com/ongil/backend/domain/review/repository/ReviewRepository.java
주문상품 ID 목록과 리뷰 타입으로 검토된 orderItem.id를 일괄 조회하는 쿼리 메서드 추가(findReviewedOrderItemIds) — N+1 방지 목적

Sequence Diagram

sequenceDiagram
    actor Client
    participant Controller as "BannerController"
    participant Service as "BannerService"
    participant OrderRepo as "OrderRepository"
    participant ReviewRepo as "ReviewRepository"
    participant Converter as "BannerConverter"

    Client->>Controller: GET /api/banner (인증된 userId)
    Controller->>Service: getBanner(userId)
    Service->>OrderRepo: 확정된 주문 조회 (조건별)
    OrderRepo-->>Service: 주문 목록

    alt 초기 리뷰 대상 존재
        Service->>ReviewRepo: 일괄 조회 (orderItemIds, INITIAL)
        ReviewRepo-->>Service: 검토된 itemIds
        Service->>Converter: toResponse(REVIEW_PROMPT, target)
        Converter-->>Service: BannerResponse
    else
        Service->>OrderRepo: 기간 기반 주문 조회 (예: 5일 이전)
        OrderRepo-->>Service: 오래된 주문 목록
        alt 한달 후 리뷰 대상 존재
            Service->>ReviewRepo: 일괄 조회 (orderItemIds, ONE_MONTH)
            ReviewRepo-->>Service: 검토된 itemIds
            Service->>Converter: toResponse(MONTHLY_REVIEW_PROMPT, target)
            Converter-->>Service: BannerResponse
        else
            Service->>Converter: toResponse(MAGAZINE, magazineUrl)
            Converter-->>Service: BannerResponse
        end
    end

    Service-->>Controller: BannerResponse
    Controller-->>Client: 200 OK { data: BannerResponse }
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

✨ Feature

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 53.85% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR 제목이 변경사항의 주요 내용을 명확하게 설명합니다. 마이페이지의 맞춤형 배너 알림 조회 API 구현이라는 핵심 기능을 정확히 반영하고 있으며, 추가된 모든 파일들(BannerController, BannerService, BannerResponse 등)이 이 목표를 지원합니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

마이페이지에서 사용자 맞춤형 배너 알림(리뷰 유도/매거진 유도)을 우선순위에 따라 조회하는 API를 추가합니다.

Changes:

  • 배너 조회 API 컨트롤러/서비스 및 응답 모델(BannerResponse, BannerType) 신규 추가
  • 주문 확정일 기준으로 주문 조회할 수 있도록 OrderRepository에 JPQL 메서드 추가
  • 배너 응답 생성을 위한 BannerConverter 추가

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.

Show a summary per file
File Description
src/main/java/com/ongil/backend/domain/order/repository/OrderRepository.java 주문 확정일(confirmedAt) 기준 사용자 주문 조회 쿼리 메서드 추가
src/main/java/com/ongil/backend/domain/banner/service/BannerService.java 배너 우선순위 결정 로직(구매직후 리뷰 → 한달/기간후 리뷰 → 매거진) 구현
src/main/java/com/ongil/backend/domain/banner/enums/BannerType.java 배너 타입 정의 추가
src/main/java/com/ongil/backend/domain/banner/dto/response/BannerResponse.java 배너 조회 응답 DTO(Record) 추가
src/main/java/com/ongil/backend/domain/banner/converter/BannerConverter.java BannerResponse 변환 로직 추가
src/main/java/com/ongil/backend/domain/banner/controller/BannerController.java 배너 조회 엔드포인트(/api/banner) 추가

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +54 to +63
OrderItem pendingItem = findPendingInitialReviewItem(order);
if (pendingItem != null) {
return bannerConverter.toResponse(
BannerType.REVIEW_PROMPT,
"구매하신 상품은 어떠셨나요?",
"작성하러 가기",
"/review/write",
order.getId(),
true
);
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

pendingItem is computed but not used, and the banner targetId is set to order.getId(). If the review-write flow needs an orderItemId (as in pending review responses), this will route users without enough context. Either set targetId to the pending OrderItem id (and keep the lookup), or remove the pendingItem lookup if orderId is truly intended.

Copilot uses AI. Check for mistakes.
"한달 후기를 작성해주세요!",
"작성하러 가기",
"/review/monthly/write",
order.getId(),
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

Same issue as above: pendingItem is computed but unused, while targetId is set to order.getId(). If the monthly review banner is meant to deep-link to a specific order item for ReviewType.ONE_MONTH, return the pending OrderItem id (or adjust the banner payload so the client can resolve the correct item).

Suggested change
order.getId(),
pendingItem.getId(),

Copilot uses AI. Check for mistakes.
Comment on lines +48 to +51
List<Order> confirmedOrders = orderRepository.findByUserIdAndStatus(
userId,
OrderStatus.CONFIRMED
);
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

findByUserIdAndStatus(...) loads all confirmed orders for the user, then scans them in memory. For users with many historical orders this can be expensive. Consider narrowing the query window (e.g., only recent confirmed orders for the “구매직후” banner) and/or using paging/limit so this endpoint stays fast.

Copilot uses AI. Check for mistakes.
Comment on lines +107 to +115
private OrderItem findPendingInitialReviewItem(Order order) {
for (OrderItem item : order.getOrderItems()) {
boolean hasInitialReview = reviewRepository.existsByOrderItemIdAndReviewType(
item.getId(),
ReviewType.INITIAL
);
if (!hasInitialReview) {
return item;
}
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

This loop can trigger N+1 DB access: order.getOrderItems() is likely lazy (one query per order), and existsByOrderItemIdAndReviewType(...) runs once per item. Consider fetching needed orderItems eagerly (fetch join / @EntityGraph) and checking review existence in bulk (e.g., query reviewed orderItemIds for the user+type) to avoid many small queries.

Copilot uses AI. Check for mistakes.
Comment on lines +70 to +85
private BannerResponse checkMonthlyReviewBanner(Long userId) {
LocalDateTime fiveDaysAgo = LocalDateTime.now().minusDays(5);

List<Order> orders = orderRepository.findByUserIdAndStatusAndConfirmedAtBefore(
userId,
OrderStatus.CONFIRMED,
fiveDaysAgo
);

for (Order order : orders) {
OrderItem pendingItem = findPendingMonthlyReviewItem(order);
if (pendingItem != null) {
return bannerConverter.toResponse(
BannerType.MONTHLY_REVIEW_PROMPT,
"한달 후기를 작성해주세요!",
"작성하러 가기",
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

The implementation uses now().minusDays(5) to decide eligibility, but the method name/comments/UI text describe this as “한달 후”/monthly. This mismatch is likely to confuse future maintenance. Please align the naming/messages/comments with the actual business rule (5 days) or update the logic to match “one month”.

Copilot uses AI. Check for mistakes.
Comment on lines +29 to +39
// 특정 사용자의 주문 확정 시간 이후 주문 조회 (5일 전 이후 확정된 주문)
@Query("SELECT o FROM Order o " +
"WHERE o.user.id = :userId " +
"AND o.orderStatus = :status " +
"AND o.confirmedAt >= :afterTime " +
"ORDER BY o.confirmedAt ASC")
List<Order> findByUserIdAndStatusAndConfirmedAtAfter(
@Param("userId") Long userId,
@Param("status") OrderStatus status,
@Param("afterTime") LocalDateTime afterTime
);
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

The inline comment says this query is for “5일 전 이후 확정된 주문”, but the method accepts an arbitrary afterTime and is currently unused. Consider making the comment generic (e.g., “after a given time”), and/or removing unused repository methods from this PR to keep the repository surface minimal.

Copilot uses AI. Check for mistakes.
Comment on lines +51 to +56
// 특정 사용자의 주문 확정 시간 이전 주문 조회 (한달 이상 경과)
@Query("SELECT o FROM Order o " +
"WHERE o.user.id = :userId " +
"AND o.orderStatus = :status " +
"AND o.confirmedAt <= :beforeTime " +
"ORDER BY o.confirmedAt DESC")
Copy link

Copilot AI Jan 28, 2026

Choose a reason for hiding this comment

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

The comment “한달 이상 경과” is misleading here because this method simply filters by an arbitrary beforeTime (and the banner service currently passes 5 days). Please either generalize the comment or ensure the calling code passes an actual “one month” threshold so terminology matches behavior.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor

@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: 2

🤖 Fix all issues with AI agents
In `@src/main/java/com/ongil/backend/domain/banner/service/BannerService.java`:
- Around line 47-118: Both checkInitialReviewBanner and checkMonthlyReviewBanner
cause N+1 queries because order.getOrderItems() is LAZY and each OrderItem
triggers reviewRepository.existsByOrderItemIdAndReviewType; fix by loading
needed OrderItems and review-existence in bulk: change the orderRepository query
used in checkInitialReviewBanner/checkMonthlyReviewBanner to fetch orders with
items (e.g., JOIN FETCH or a new repository method that returns orders with
orderItems) or separately load all OrderItems for the returned orders using a
single query, then call reviewRepository with an IN-based query (e.g., exists or
find by orderItemId IN and ReviewType) to get all reviewed item IDs at once and
use that set inside findPendingInitialReviewItem/findPendingMonthlyReviewItem to
avoid per-item exists calls.
- Around line 70-77: The constant name/value mismatch must be resolved by
deciding whether the threshold is 5 days or 30 days and applying the change
across services: if 5 days is correct, rename
ReviewService.ONE_MONTH_REVIEW_AVAILABLE_DAYS to MONTHLY_REVIEW_AVAILABLE_DAYS
(or MOVE the constant to a shared config/Constants class) and update
BannerService.checkMonthlyReviewBanner to reference that renamed/shared constant
and adjust the banner message text to reflect "available in 5 days" semantics;
if one-month (30 days) is intended, change the constant value to 30 in
ReviewService (or shared Constants), update
BannerService.checkMonthlyReviewBanner to use the same shared constant, and
update the banner message to "write your review after one month"
accordingly—ensure both services reference the same constant (e.g.,
ReviewService.ONE_MONTH_REVIEW_AVAILABLE_DAYS or new shared constant) and align
the displayed message with the chosen threshold.

Comment on lines +47 to +118
private BannerResponse checkInitialReviewBanner(Long userId) {
List<Order> confirmedOrders = orderRepository.findByUserIdAndStatus(
userId,
OrderStatus.CONFIRMED
);

for (Order order : confirmedOrders) {
OrderItem pendingItem = findPendingInitialReviewItem(order);
if (pendingItem != null) {
return bannerConverter.toResponse(
BannerType.REVIEW_PROMPT,
"구매하신 상품은 어떠셨나요?",
"작성하러 가기",
"/review/write",
order.getId(),
true
);
}
}

return null;
}

private BannerResponse checkMonthlyReviewBanner(Long userId) {
LocalDateTime fiveDaysAgo = LocalDateTime.now().minusDays(5);

List<Order> orders = orderRepository.findByUserIdAndStatusAndConfirmedAtBefore(
userId,
OrderStatus.CONFIRMED,
fiveDaysAgo
);

for (Order order : orders) {
OrderItem pendingItem = findPendingMonthlyReviewItem(order);
if (pendingItem != null) {
return bannerConverter.toResponse(
BannerType.MONTHLY_REVIEW_PROMPT,
"한달 후기를 작성해주세요!",
"작성하러 가기",
"/review/monthly/write",
order.getId(),
true
);
}
}

return null;
}

private BannerResponse createMagazineBanner() {
return bannerConverter.toResponse(
BannerType.MAGAZINE,
"추천 매거진을 확인해보세요",
"보러가기",
"/magazine",
null,
true
);
}

private OrderItem findPendingInitialReviewItem(Order order) {
for (OrderItem item : order.getOrderItems()) {
boolean hasInitialReview = reviewRepository.existsByOrderItemIdAndReviewType(
item.getId(),
ReviewType.INITIAL
);
if (!hasInitialReview) {
return item;
}
}
return null;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cd src/main/java/com/ongil/backend/domain/banner && find . -type f -name "*.java"

Repository: IT-Cotato/12th-OnGil-BE

Length of output: 222


🏁 Script executed:

cat -n src/main/java/com/ongil/backend/domain/banner/service/BannerService.java | head -150

Repository: IT-Cotato/12th-OnGil-BE

Length of output: 4410


🏁 Script executed:

find . -path "*/order/repository/*" -name "*.java" | head -5

Repository: IT-Cotato/12th-OnGil-BE

Length of output: 228


🏁 Script executed:

find . -path "*/review/repository/*" -name "*.java" | head -5

Repository: IT-Cotato/12th-OnGil-BE

Length of output: 235


🏁 Script executed:

cat -n src/main/java/com/ongil/backend/domain/order/repository/OrderRepository.java

Repository: IT-Cotato/12th-OnGil-BE

Length of output: 2493


🏁 Script executed:

cat -n src/main/java/com/ongil/backend/domain/review/repository/ReviewRepository.java

Repository: IT-Cotato/12th-OnGil-BE

Length of output: 8046


🏁 Script executed:

find . -path "*/order/entity/*" -name "Order.java"

Repository: IT-Cotato/12th-OnGil-BE

Length of output: 131


🏁 Script executed:

cat -n src/main/java/com/ongil/backend/domain/order/entity/Order.java

Repository: IT-Cotato/12th-OnGil-BE

Length of output: 3461


🏁 Script executed:

find . -path "*/order/entity/*" -name "OrderItem.java"

Repository: IT-Cotato/12th-OnGil-BE

Length of output: 135


🏁 Script executed:

cat -n src/main/java/com/ongil/backend/domain/order/entity/OrderItem.java

Repository: IT-Cotato/12th-OnGil-BE

Length of output: 2045


🏁 Script executed:

cat -n src/main/java/com/ongil/backend/domain/review/entity/Review.java | head -50

Repository: IT-Cotato/12th-OnGil-BE

Length of output: 1827


주문/아이템 반복 순회 + 항목별 exists 호출로 N+1 쿼리 발생 확인됨

checkInitialReviewBanner(), checkMonthlyReviewBanner() 메서드에서:

  1. findByUserIdAndStatus() 또는 findByUserIdAndStatusAndConfirmedAtBefore() → 1회 조회
  2. 각 Order마다 order.getOrderItems() → 지연로딩으로 N회 추가 쿼리
  3. 각 OrderItem마다 reviewRepository.existsByOrderItemIdAndReviewType() → M회 추가 쿼리

Order 엔티티(line 74)의 @OneToMany는 기본값 LAZY로 설정되어 있어 반복문 내 getOrderItems() 호출마다 DB 쿼리가 발생합니다. 확정 주문이 많은 사용자의 경우 쿼리 폭증으로 인한 성능 저하가 명확합니다.

JOIN FETCH, 서브쿼리, 또는 IN 절 기반 일괄 조회 최적화를 권장합니다. 예를 들어 미작성 리뷰 아이템을 DB에서 한 번에 조회하는 방식으로 개선 가능합니다.

🤖 Prompt for AI Agents
In `@src/main/java/com/ongil/backend/domain/banner/service/BannerService.java`
around lines 47 - 118, Both checkInitialReviewBanner and
checkMonthlyReviewBanner cause N+1 queries because order.getOrderItems() is LAZY
and each OrderItem triggers reviewRepository.existsByOrderItemIdAndReviewType;
fix by loading needed OrderItems and review-existence in bulk: change the
orderRepository query used in checkInitialReviewBanner/checkMonthlyReviewBanner
to fetch orders with items (e.g., JOIN FETCH or a new repository method that
returns orders with orderItems) or separately load all OrderItems for the
returned orders using a single query, then call reviewRepository with an
IN-based query (e.g., exists or find by orderItemId IN and ReviewType) to get
all reviewed item IDs at once and use that set inside
findPendingInitialReviewItem/findPendingMonthlyReviewItem to avoid per-item
exists calls.

Comment on lines +70 to +77
private BannerResponse checkMonthlyReviewBanner(Long userId) {
LocalDateTime fiveDaysAgo = LocalDateTime.now().minusDays(5);

List<Order> orders = orderRepository.findByUserIdAndStatusAndConfirmedAtBefore(
userId,
OrderStatus.CONFIRMED,
fiveDaysAgo
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

fd BannerService.java

Repository: IT-Cotato/12th-OnGil-BE

Length of output: 139


🏁 Script executed:

cat -n src/main/java/com/ongil/backend/domain/banner/service/BannerService.java | head -100

Repository: IT-Cotato/12th-OnGil-BE

Length of output: 3515


🏁 Script executed:

rg "checkMonthlyReviewBanner" -A 30 -B 5

Repository: IT-Cotato/12th-OnGil-BE

Length of output: 6586


🏁 Script executed:

rg "한달|monthly|Monthly" --type java

Repository: IT-Cotato/12th-OnGil-BE

Length of output: 3315


🏁 Script executed:

rg "주문 완료 5일 후" -A 10 -B 5

Repository: IT-Cotato/12th-OnGil-BE

Length of output: 1849


🏁 Script executed:

rg "findPendingMonthlyReviewItem" -A 20

Repository: IT-Cotato/12th-OnGil-BE

Length of output: 3316


🏁 Script executed:

fd -e java -path "*/test/*" BannerService | head -5

Repository: IT-Cotato/12th-OnGil-BE

Length of output: 235


🏁 Script executed:

rg "ONE_MONTH" -A 5 -B 5 --type java

Repository: IT-Cotato/12th-OnGil-BE

Length of output: 9555


상수명과 실제 임계값의 의도 불일치를 정합성 있게 정리해야 합니다.

5일 기준은 ReviewService의 ONE_MONTH_REVIEW_AVAILABLE_DAYS = 5 상수로 의도적으로 설정되어 있으며, BannerService와 ReviewService에서 일관되게 사용 중입니다. 다만 문제는:

  • 상수명이 "ONE_MONTH"인데 실제값은 5(일)
  • 배너 메시지는 "한달 후기를 작성해주세요!"이지만 실제 조건은 5일

변경할 경우 BannerService만 수정하면 ReviewService와 불일치하므로, 설계 의도를 명확히 한 뒤 양쪽을 함께 정합하세요:

  • 5일이 의도라면: 상수 이름을 MONTHLY_REVIEW_AVAILABLE_DAYS로 개명하고 메시지 의도 재검토
  • 1달이 의도라면: 상수값을 30으로 변경하고 양쪽 서비스 일괄 수정
🤖 Prompt for AI Agents
In `@src/main/java/com/ongil/backend/domain/banner/service/BannerService.java`
around lines 70 - 77, The constant name/value mismatch must be resolved by
deciding whether the threshold is 5 days or 30 days and applying the change
across services: if 5 days is correct, rename
ReviewService.ONE_MONTH_REVIEW_AVAILABLE_DAYS to MONTHLY_REVIEW_AVAILABLE_DAYS
(or MOVE the constant to a shared config/Constants class) and update
BannerService.checkMonthlyReviewBanner to reference that renamed/shared constant
and adjust the banner message text to reflect "available in 5 days" semantics;
if one-month (30 days) is intended, change the constant value to 30 in
ReviewService (or shared Constants), update
BannerService.checkMonthlyReviewBanner to use the same shared constant, and
update the banner message to "write your review after one month"
accordingly—ensure both services reference the same constant (e.g.,
ReviewService.ONE_MONTH_REVIEW_AVAILABLE_DAYS or new shared constant) and align
the displayed message with the chosen threshold.

Copy link
Copy Markdown
Contributor

@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

🤖 Fix all issues with AI agents
In `@src/main/java/com/ongil/backend/domain/banner/service/BannerService.java`:
- Around line 81-87: BannerService constructs a REVIEW_PROMPT banner using
bannerConverter.toResponse but incorrectly passes order.getId() as the targetId
while it checks reviewedOrderItemIds.contains(item.getId()); change the targetId
argument in the bannerConverter.toResponse calls (the REVIEW_PROMPT cases) to
pass item.getId() instead of order.getId() so the banner targets the specific
OrderItem (ensure types match for item.getId())—update both occurrences where
BannerType.REVIEW_PROMPT is created.

@neibler neibler merged commit d198cd2 into develop Jan 28, 2026
1 check 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.

2 participants