Conversation
- durationSeconds가 무기한을 의미하는 값(약 100년 = 3,153,600,000초)일 때 기존 로직에서 시,분 단위로 변환되지 못하는 문제 수정 - 무기한일 경우 시,분 대신 프론트와 무한으로 정한 컨벤션인 (-1, -1)로 변환되도록 처리 - Long -> Duration -> Long 으로 불필요한 변환 작업이 이루어져 단순화
|
Warning You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again! |
WalkthroughReservedTimeInfo의 지속시간 표현을 Duration에서 long 초 단위로 변경하고, 무기한(-1/-1) 처리를 상수 기반으로 통일했습니다. MemberService는 toSeconds()를 사용하고, 역변환 시 INDEFINITE_SECONDS를 INDEFINITE_HOUR/MINUTE로 매핑합니다. 공통 상수 클래스(StatusReserveTimeConstants)를 신규 추가했습니다. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Client
participant Controller
participant MemberService
participant ReservedTimeInfo
participant Constants as StatusReserveTimeConstants
Client->>Controller: updateStatus(request)
Controller->>MemberService: updateStatus(request)
MemberService->>ReservedTimeInfo: request.reservedTimeInfo().toSeconds()
Note over ReservedTimeInfo,Constants: hour/minute가 무기한(-1/-1)면<br/>INDEFINITE_SECONDS 반환
ReservedTimeInfo-->>MemberService: seconds
alt seconds == INDEFINITE_SECONDS
MemberService->>MemberService: createReservedTimeInfo(seconds)
Note over MemberService,Constants: INDEFINITE_SECONDS ↔ (-1, -1) 역매핑
else seconds != INDEFINITE_SECONDS
MemberService->>MemberService: createReservedTimeInfo(seconds)<br/>(시/분 계산: /3600, %60)
end
MemberService-->>Controller: 상태 업데이트 결과
Controller-->>Client: 응답
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10–15 minutes Assessment against linked issues
Assessment against linked issues: Out-of-scope changes(해당 없음) Possibly related PRs
Suggested reviewers
✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
Status, Documentation and Community
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (8)
src/main/java/com/example/wini/global/common/constant/StatusReserveTimeConstants.java (3)
3-3: 상수 홀더는 상속 불가로 고정하세요.유틸리티 성격의 상수 클래스는
final지정이 관례입니다.-public class StatusReserveTimeConstants { +public final class StatusReserveTimeConstants {
5-6: 초 단위 상수를 long으로 올려 형 변환 및 곱셈 시 안전성을 확보하세요.
hour * SECONDS_PER_HOUR연산에서hour가long이므로 상수도long이 더 안전합니다.- public static final int SECONDS_PER_HOUR = 3600; - public static final int SECONDS_PER_MINUTE = 60; + public static final long SECONDS_PER_HOUR = 3600L; + public static final long SECONDS_PER_MINUTE = 60L;
8-10: 무기한 시간 sentinel 명칭 개선 및 DB 컬럼 타입 검증 필요
- 상수명
INDEFINITE_SECONDS를INDEFINITE_SECONDS_SENTINEL로 변경하고, 관련 사용처(예: 비교연산)도 함께 수정하세요.- public static final long INDEFINITE_SECONDS = 365L * 100 * 24 * 60 * 60; + /** 무기한 상태를 나타내는 sentinel 값(약 100년) */ + public static final long INDEFINITE_SECONDS_SENTINEL = 365L * 100 * 24 * 60 * 60;
- Java 필드
statusDuration는 Long이지만, 실제 DBstatus_duration컬럼이 INT일 경우 overflow 위험이 있습니다. JPA 매핑과 마이그레이션(DDL/XML/YAML) 파일을 확인해 BIGINT 보장이 필요한지 검증해주세요.src/main/java/com/example/wini/domain/member/service/MemberService.java (3)
82-84: 시간 역산 시 허용 범위 초과 값에 대한 방어 로직을 권장합니다.DB나 과거 데이터로 인해 12시간 초과/음수 등이 들어올 경우 응답 모델 제약(@max 12/@max 59)과 불일치할 수 있습니다. Fail-fast 검증 또는 로그+클램프 중 하나를 고려하세요.
- Duration duration = Duration.ofSeconds(durationSeconds); - return ReservedTimeInfo.of(duration.toHours(), duration.toMinutes() % 60); + Duration duration = Duration.ofSeconds(durationSeconds); + long hours = duration.toHours(); + long minutes = duration.toMinutes() % 60; + if (hours < 0 || minutes < 0 || hours > 12 || minutes > 59) { + throw new IllegalArgumentException("Invalid status duration: " + durationSeconds + "s"); + } + return ReservedTimeInfo.of(hours, minutes);
93-93: 불필요한 오토박싱 제거:Long→long.원시형 사용으로 가비지 최소화 및 NPE 가능성 제거.
- Long statusDurationSeconds = request.reservedTimeInfo().toSeconds(); + long statusDurationSeconds = request.reservedTimeInfo().toSeconds();
69-75: 시간 비교의 테스트 용이성 향상(Clock 주입).
LocalDateTime.now()대신Clock주입 후LocalDateTime.now(clock)사용을 권장합니다.예시:
- private boolean isStatusValid(Member member) { + private final Clock clock; + private boolean isStatusValid(Member member) { ... - return endTime.isAfter(LocalDateTime.now()); + return endTime.isAfter(LocalDateTime.now(clock));src/main/java/com/example/wini/domain/member/dto/common/ReservedTimeInfo.java (2)
19-24: toSeconds 구현은 간결하고 맞습니다. 다만 상수 타입을 long으로 통일하면 더 안전합니다.상수 타입 변경(PR 내 제안)과 함께라면 오버플로 경계가 더 명확해집니다.
13-17: 래퍼(Long) 대신 원시형(long) 고려.필드가
@NotNull제약을 이미 요구하므로long사용이 일관성과 NPE 방지 측면에서 이점이 있습니다(직렬화 정책에 영향 없는지 확인 필요).
📜 Review details
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
src/main/java/com/example/wini/domain/member/dto/common/ReservedTimeInfo.java(1 hunks)src/main/java/com/example/wini/domain/member/service/MemberService.java(3 hunks)src/main/java/com/example/wini/global/common/constant/StatusReserveTimeConstants.java(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/main/java/com/example/wini/domain/member/service/MemberService.java (1)
src/main/java/com/example/wini/global/common/constant/StatusReserveTimeConstants.java (1)
StatusReserveTimeConstants(3-13)
src/main/java/com/example/wini/domain/member/dto/common/ReservedTimeInfo.java (1)
src/main/java/com/example/wini/global/common/constant/StatusReserveTimeConstants.java (1)
StatusReserveTimeConstants(3-13)
⏰ 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: build-deploy
🔇 Additional comments (2)
src/main/java/com/example/wini/domain/member/service/MemberService.java (2)
3-5: 무기한 변환을 위한 상수 정리, 잘 반영되었습니다.
77-81: 무기한(sentinel) 역변환 처리 LGTM.
durationSeconds == INDEFINITE_SECONDS→(-1, -1)매핑으로 이슈(#92) 원인을 정확히 해소합니다.
| public long toSeconds() { | ||
| if (this.hour == INDEFINITE_HOUR && this.minute == INDEFINITE_MINUTE) { | ||
| return INDEFINITE_SECONDS; | ||
| } | ||
|
|
||
| return Duration.ofHours(this.hour).plusMinutes(this.minute); | ||
| return this.hour * SECONDS_PER_HOUR + this.minute * SECONDS_PER_MINUTE; | ||
| } |
There was a problem hiding this comment.
무기한(-1/-1) 조합 불일치 시 음수 초 산출 가능성 — 방어 필요.
hour=-1, minute=30 같은 케이스에서 음수 초가 계산됩니다. 무기한은 양쪽이 동시에 -1이어야만 유효하도록 강제하세요(레코드 compact 생성자 사용 권장).
public record ReservedTimeInfo(
@NotNull @Min(value = -1) @Max(value = 12) Long hour, @NotNull @Min(value = -1) @Max(value = 59) Long minute) {
+ public ReservedTimeInfo {
+ boolean hourIndef = hour != null && hour == INDEFINITE_HOUR;
+ boolean minIndef = minute != null && minute == INDEFINITE_MINUTE;
+ if (hourIndef ^ minIndef) {
+ throw new IllegalArgumentException("Indefinite must be (-1, -1).");
+ }
+ if (!hourIndef) {
+ if (hour < 0 || hour > 12 || minute < 0 || minute > 59) {
+ throw new IllegalArgumentException("hour/minute out of range.");
+ }
+ }
+ }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| public long toSeconds() { | |
| if (this.hour == INDEFINITE_HOUR && this.minute == INDEFINITE_MINUTE) { | |
| return INDEFINITE_SECONDS; | |
| } | |
| return Duration.ofHours(this.hour).plusMinutes(this.minute); | |
| return this.hour * SECONDS_PER_HOUR + this.minute * SECONDS_PER_MINUTE; | |
| } | |
| public record ReservedTimeInfo( | |
| @NotNull @Min(value = -1) @Max(value = 12) Long hour, | |
| @NotNull @Min(value = -1) @Max(value = 59) Long minute) { | |
| // Enforce that “indefinite” is only allowed when both hour and minute are –1, | |
| // otherwise both must be within their respective valid ranges. | |
| public ReservedTimeInfo { | |
| boolean hourIndef = hour != null && hour == INDEFINITE_HOUR; | |
| boolean minIndef = minute != null && minute == INDEFINITE_MINUTE; | |
| if (hourIndef ^ minIndef) { | |
| throw new IllegalArgumentException("Indefinite must be (-1, -1)."); | |
| } | |
| if (!hourIndef) { | |
| if (hour < 0 || hour > 12 || minute < 0 || minute > 59) { | |
| throw new IllegalArgumentException("hour/minute out of range."); | |
| } | |
| } | |
| } | |
| public long toSeconds() { | |
| if (this.hour == INDEFINITE_HOUR && this.minute == INDEFINITE_MINUTE) { | |
| return INDEFINITE_SECONDS; | |
| } | |
| return this.hour * SECONDS_PER_HOUR + this.minute * SECONDS_PER_MINUTE; | |
| } | |
| } |
🤖 Prompt for AI Agents
In src/main/java/com/example/wini/domain/member/dto/common/ReservedTimeInfo.java
around lines 19 to 24, the toSeconds() method can produce negative results when
only one field is INDEFINITE (e.g. hour = -1, minute = 30); change the logic to
treat indefinite only when both hour and minute equal INDEFINITE constants, and
defensively validate the fields otherwise: if one is INDEFINITE and the other is
not, throw an IllegalArgumentException (or IllegalStateException) to prevent
computing negative seconds, and ensure normal path validates non-negative
hour/minute before computing seconds; additionally enforce this invariant in the
record compact constructor so instances cannot be created with a single -1.
🌱 관련 이슈
📌 작업 내용 및 특이사항
📝 참고사항
📚 기타
Summary by CodeRabbit