Skip to content

[FIX] #205

Open
88guri wants to merge 1 commit intodevelopfrom
refact/#79/add-review-ema
Open

[FIX] #205
88guri wants to merge 1 commit intodevelopfrom
refact/#79/add-review-ema

Conversation

@88guri
Copy link
Copy Markdown
Collaborator

@88guri 88guri commented Jan 23, 2026

📌 관련 이슈

✨ 변경 사항

  • ema 도입 에러 발생 이유가 nullable 적용을 해놨는데 double, long, int를 사용함
  • 이를 Double, Long, Integer로 변경

📸 테스트 증명 (필수)

📚 리뷰어 참고 사항

✅ 체크리스트

  • 브랜치 전략(git flow)을 따랐나요? (develop -> feat/...)
  • 로컬에서 빌드 및 실행이 정상적으로 되나요?
  • 불필요한 주석(TODO 등)이나 더미 코드는 제거했나요?
  • 컨벤션(커밋 메시지, 코드 스타일)을 지켰나요?

Summary by CodeRabbit

릴리스 노트

  • Refactor
    • 내부 평점 데이터 저장 구조 개선으로 시스템 안정성을 강화했습니다.

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

@88guri 88guri requested a review from PBEM22 January 23, 2026 14:18
@88guri 88guri self-assigned this Jan 23, 2026
@88guri 88guri added 🚨 Fix 버그 수정 🐵 시현 시현이에요 🌟Review 리뷰 labels Jan 23, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jan 23, 2026

📝 Walkthrough

Walkthrough

세 개의 엔티티 클래스(GroupBuyPost, User)와 서비스 클래스(ReviewApplicationService)에서 rating 관련 필드들을 primitive 타입에서 wrapper 타입으로 변경하는 작업입니다. User 엔티티의 경우 데이터베이스 컬럼의 nullable 속성도 false에서 true로 조정되었습니다.

Changes

Cohort / File(s) 요약
Rating 필드 타입 변경
src/main/java/org/sopt/poti/domain/groupbuy/entity/GroupBuyPost.java
ratingAvg (double → Double), ratingSum (long → Long), ratingCount (int → Integer)로 변경
서비스 레이어 변수 타입 조정
src/main/java/org/sopt/poti/domain/review/application/ReviewApplicationService.java
로컬 변수 reviewCount, postAvg 타입을 wrapper 타입으로 조정
User 엔티티 타입 및 nullable 변경
src/main/java/org/sopt/poti/domain/user/entity/User.java
ratingSum (long → Long), ratingCount (int → Integer)로 변경 및 @Column(nullable = true)로 조정

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

♻️ Refactor, ☁️ P2

Suggested reviewers

  • PBEM22

기술적 검토

전체적으로 primitive type에서 wrapper type으로의 전환은 일관성 있게 적용되었는데, 몇 가지 짚고 넘어갈 부분이 있네요:

1. Nullability 처리 재검토
User 엔티티에서 nullable = true로 변경했으니, 실제 비즈니스 로직에서 null 값을 받을 가능성을 모두 고려했는지 확인이 필요합니다. 특히 ratingSumratingCount가 null이 될 때 계산 로직들이 제대로 처리되는지 살펴봐야 할 것 같습니다.

2. GroupBuyPost의 초기값
ratingAvg = 0.0, ratingSum = 0L, ratingCount = 0으로 초기화되어 있는데, 이게 DB 스키마에도 제대로 반영되어 있는지 확인하면 좋을 것 같습니다.

3. EMA 도입과의 연계
이슈 #79에서 EMA(지수 이동 평균) 도입을 언급하고 있는데, 이번 타입 변경이 그 작업을 위한 사전 단계인 것 같습니다. 다음 단계에서 실제 EMA 계산 로직이 제대로 동작하도록 설계되었는지 염두에 두세요.

🚥 Pre-merge checks | ✅ 3 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Title check ⚠️ Warning PR 제목이 너무 불완전하고 구체적이지 않음. '[FIX]'만 있어서 어떤 내용을 수정했는지 전혀 알 수 없음. 제목을 '[FIX] Null 타입 관련 오류 해결을 위해 primitive 타입을 wrapper 타입으로 변경' 같이 변경사항을 명확하게 설명하는 구체적인 제목으로 수정해주세요.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed PR의 변경사항(primitive → wrapper 타입 변환)이 이슈 #79의 EMA 도입 요구사항 충족을 위한 필수 수정이며, 관련 변경이 적절히 구현되었음.
Out of Scope Changes check ✅ Passed 모든 변경사항이 EMA 도입 시 발생한 null 관련 오류를 해결하기 위한 타입 변환으로, 이슈 #79의 범위 내에서 필요한 수정임.

✏️ 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

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

🤖 Fix all issues with AI agents
In `@src/main/java/org/sopt/poti/domain/groupbuy/entity/GroupBuyPost.java`:
- Around line 75-82: The rating fields ratingAvg, ratingSum, and ratingCount can
be null (DB nullable) which risks NPEs in addRating due to auto-unboxing; update
addRating to defensively handle nulls by treating null as 0 (e.g., coerce
ratingSum/ratingCount/ratingAvg to 0 before arithmetic) or add a
`@PostLoad/`@PrePersist initializer that backfills null fields to 0, and ensure
any setters also guard against null inputs; reference the fields ratingAvg,
ratingSum, ratingCount and the addRating method when applying the fix.

In
`@src/main/java/org/sopt/poti/domain/review/application/ReviewApplicationService.java`:
- Around line 44-45: The code in ReviewApplicationService reads Integer
reviewCount = post.getRatingCount() and Double postAvg = post.getRatingAvg() but
GroupBuyPost's rating fields can be null; update ReviewApplicationService to
null-safe defaults (e.g., reviewCount -> 0, postAvg -> 0.0) before any
arithmetic/logic, and use those non-null primitives or safe wrappers when
calling downstream methods; apply the same null-coalescing fix to the other
occurrence referenced (the second block around lines 50) so both
reviewCount/postAvg usages are protected.

In `@src/main/java/org/sopt/poti/domain/user/entity/User.java`:
- Around line 59-63: The User entity's ratingSum/ratingCount are declared
nullable which risks NPEs where callers (ReviewApplicationService: reviewCount =
post.getRatingCount(); and GroupBuyPost methods updating/reading ratings)
perform unboxing or arithmetic; fix by making the DB columns non-nullable and
preserving the zero defaults: set `@Column`(name = "rating_sum", nullable = false)
and `@Column`(name = "rating_count", nullable = false) on User.ratingSum and
User.ratingCount (keep the initializers 0L/0), and then audit
usages—specifically ReviewApplicationService where reviewCount is assigned and
GroupBuyPost methods that do this.ratingSum += score / this.ratingCount += 1 /
divisions—to rely on non-null values (no further null checks required after this
change) or, if you prefer code-side hardening instead, wrap reads with
Objects.requireNonNullElse(post.getRatingCount(), 0) and
Objects.requireNonNullElse(post.getRatingSum(), 0L) in ReviewApplicationService
and use the same null-safe reads inside GroupBuyPost before mutating or
dividing.

Comment on lines 75 to +82
@Column(name = "rating_avg", nullable = true)
private double ratingAvg = 0.0; //공구 글 당 평점
private Double ratingAvg = 0.0; //공구 글 당 평점

@Column(name = "rating_sum", nullable = true)
private long ratingSum = 0L;
private Long ratingSum = 0L;

@Column(name = "rating_count", nullable = true)
private int ratingCount = 0;
private Integer ratingCount = 0;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Nullable로 바뀐 rating 필드가 null이면 addRating에서 NPE 가능성 있습니다.

컬럼이 nullable이면 기존 데이터가 null로 로드될 수 있고, += 연산에서 오토 언박싱으로 NPE가 발생할 수 있습니다. 최소한 addRating 진입 시 null-safe 보정(또는 @PostLoad/@PrePersist, 백필) 처리가 필요합니다.

🛠️ 제안 수정
 public void addRating(int score) {
   validateScore(score);

+  if (this.ratingSum == null) this.ratingSum = 0L;
+  if (this.ratingCount == null) this.ratingCount = 0;
+  if (this.ratingAvg == null) this.ratingAvg = 0.0;
+
   this.ratingSum += score;
   this.ratingCount += 1;

-  Double avg = (double) this.ratingSum / this.ratingCount;
+  double avg = (double) this.ratingSum / this.ratingCount;
   this.ratingAvg = Math.round(avg * 10) / 10.0;
 }

Also applies to: 210-218

🤖 Prompt for AI Agents
In `@src/main/java/org/sopt/poti/domain/groupbuy/entity/GroupBuyPost.java` around
lines 75 - 82, The rating fields ratingAvg, ratingSum, and ratingCount can be
null (DB nullable) which risks NPEs in addRating due to auto-unboxing; update
addRating to defensively handle nulls by treating null as 0 (e.g., coerce
ratingSum/ratingCount/ratingAvg to 0 before arithmetic) or add a
`@PostLoad/`@PrePersist initializer that backfills null fields to 0, and ensure
any setters also guard against null inputs; reference the fields ratingAvg,
ratingSum, ratingCount and the addRating method when applying the fix.

Comment on lines +44 to +45
Integer reviewCount = post.getRatingCount();
Double postAvg = post.getRatingAvg();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

postAvg/reviewCount null 가능성 처리 필요합니다.

GroupBuyPost의 rating 필드가 nullable로 바뀌어 null이 반환될 수 있습니다. 그대로 전달하면 내부 연산에서 NPE/오동작 위험이 있습니다. null-safe 기본값 보정 후 전달하는 편이 안전합니다.

🛠️ 제안 수정
 GroupBuyPost post = groupBuyService.getPostWithLock(postId);
 Integer reviewCount = post.getRatingCount();
 Double postAvg = post.getRatingAvg();
+Integer safeReviewCount = (reviewCount != null) ? reviewCount : 0;
+Double safePostAvg = (postAvg != null) ? postAvg : 0.0;

 int postCount = groupBuyService.countPostsByLeader(sellerId);

 // 3 판매자 평점 반영
-userService.applyPostContribution(sellerId, postId, postAvg, reviewCount, postCount);
+userService.applyPostContribution(sellerId, postId, safePostAvg, safeReviewCount, postCount);

Also applies to: 50-50

🤖 Prompt for AI Agents
In
`@src/main/java/org/sopt/poti/domain/review/application/ReviewApplicationService.java`
around lines 44 - 45, The code in ReviewApplicationService reads Integer
reviewCount = post.getRatingCount() and Double postAvg = post.getRatingAvg() but
GroupBuyPost's rating fields can be null; update ReviewApplicationService to
null-safe defaults (e.g., reviewCount -> 0, postAvg -> 0.0) before any
arithmetic/logic, and use those non-null primitives or safe wrappers when
calling downstream methods; apply the same null-coalescing fix to the other
occurrence referenced (the second block around lines 50) so both
reviewCount/postAvg usages are protected.

Comment on lines +59 to +63
@Column(name = "rating_sum", nullable = true)
private Long ratingSum = 0L;

@Column(name = "rating_count", nullable = false)
private int ratingCount = 0;
@Column(name = "rating_count", nullable = true)
private Integer ratingCount = 0;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find all usages of ratingSum and ratingCount in the codebase
rg -n --type java -C3 '(getRatingSum|getRatingCount|ratingSum|ratingCount)' --max-count=100

Repository: team-poti/POTI-SERVER

Length of output: 3802


🏁 Script executed:

#!/bin/bash
# Check if Lombok is used and look for getter method patterns
rg -n --type java '@Getter|@Data|getRatingSum|getRatingCount' src/main/java/org/sopt/poti/domain/user/entity/User.java src/main/java/org/sopt/poti/domain/groupbuy/entity/GroupBuyPost.java -A2 -B2

echo "---"

# Search for all method calls and usages beyond the initial results
rg -n --type java 'getRatingSum|getRatingCount' --max-count=200

Repository: team-poti/POTI-SERVER

Length of output: 1083


🏁 Script executed:

#!/bin/bash
# Check ReviewApplicationService context around the usage
cat -n src/main/java/org/sopt/poti/domain/review/application/ReviewApplicationService.java | sed -n '35,65p'

echo "---"

# Also check for any arithmetic operations or method calls on ratingCount/ratingSum
rg -n --type java '(ratingCount|ratingSum)\s*[+\-*/=<>]|ratingCount\s*\)|\+\s*(ratingCount|ratingSum)' -A2 -B2

Repository: team-poti/POTI-SERVER

Length of output: 3059


ratingSum/ratingCount nullable 설정 시 NPE 위험성 확인 필요

DB 컬럼이 nullable = true로 설정되어 있는데, 코드에서 null 체크 없이 언박싱 연산을 수행하고 있습니다.

  • ReviewApplicationService.java L44: Integer reviewCount = post.getRatingCount(); - null이 반환되면 int 할당 시 NPE 발생
  • GroupBuyPost.java L213-217: this.ratingSum += score;, this.ratingCount += 1;, 나눗셈 연산 등에서 null 값 처리 없음

마이그레이션이나 기존 데이터에 null이 존재한다면 런타임 오류가 발생할 수 있으니, 다음 중 하나를 확인/적용해주세요:

  • 모든 사용처에 null 안전성 처리 추가
  • DB 마이그레이션으로 기존 null 값을 기본값으로 변경
  • nullable = false로 변경 (기본값 설정이 이미 되어 있으므로)
🤖 Prompt for AI Agents
In `@src/main/java/org/sopt/poti/domain/user/entity/User.java` around lines 59 -
63, The User entity's ratingSum/ratingCount are declared nullable which risks
NPEs where callers (ReviewApplicationService: reviewCount =
post.getRatingCount(); and GroupBuyPost methods updating/reading ratings)
perform unboxing or arithmetic; fix by making the DB columns non-nullable and
preserving the zero defaults: set `@Column`(name = "rating_sum", nullable = false)
and `@Column`(name = "rating_count", nullable = false) on User.ratingSum and
User.ratingCount (keep the initializers 0L/0), and then audit
usages—specifically ReviewApplicationService where reviewCount is assigned and
GroupBuyPost methods that do this.ratingSum += score / this.ratingCount += 1 /
divisions—to rely on non-null values (no further null checks required after this
change) or, if you prefer code-side hardening instead, wrap reads with
Objects.requireNonNullElse(post.getRatingCount(), 0) and
Objects.requireNonNullElse(post.getRatingSum(), 0L) in ReviewApplicationService
and use the same null-safe reads inside GroupBuyPost before mutating or
dividing.

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

Labels

🚨 Fix 버그 수정 🌟Review 리뷰 🐵 시현 시현이에요

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[REFACTOR] 별점에 EMA 도입

1 participant