Skip to content

fix: 상태 지속시간 미설정 시 역변환 안되는 오류#93

Merged
duol9 merged 3 commits intodevelopfrom
feature/89-healt-check
Aug 29, 2025
Merged

fix: 상태 지속시간 미설정 시 역변환 안되는 오류#93
duol9 merged 3 commits intodevelopfrom
feature/89-healt-check

Conversation

@duol9
Copy link
Collaborator

@duol9 duol9 commented Aug 29, 2025

🌱 관련 이슈

📌 작업 내용 및 특이사항

  • 상태 예약시간 무한값 변환 오류 수정

📝 참고사항

  • 상태 예약시간이 무기한을 의미하는 값(약 100년 = 3,153,600,000초)일 때 기존 로직에서 시,분 단위로 변환되지 못하는 문제가 발생해 이를 수정하였습니다.

📚 기타

Summary by CodeRabbit

  • 신기능
    • 예약 시간에서 “무기한” 상태를 명확히 지원하여 표시/처리가 일관됩니다.
  • 버그 수정
    • 시간 계산 방식 개선으로 간헐적 표시 오차와 해석 문제를 완화했습니다.
  • 리팩터링
    • 시간 단위 처리를 초 단위 기반으로 단순화해 안정성과 유지보수성을 높였습니다.
  • 잡무(Chores)
    • 시간 관련 상수를 중앙에서 관리하도록 정리해 향후 설정과 확장을 용이하게 했습니다.

duol9 added 3 commits August 29, 2025 22:08
- durationSeconds가 무기한을 의미하는 값(약 100년 = 3,153,600,000초)일 때 기존 로직에서 시,분 단위로 변환되지 못하는 문제 수정
- 무기한일 경우 시,분 대신 프론트와 무한으로 정한 컨벤션인 (-1, -1)로 변환되도록 처리
- Long -> Duration -> Long 으로 불필요한 변환 작업이 이루어져 단순화
@duol9 duol9 self-assigned this Aug 29, 2025
@duol9 duol9 added 🐛 fix 버그 및 에러 픽스 🥇 P1 급하고 꼭 필요한 이슈 labels Aug 29, 2025
@gemini-code-assist
Copy link

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@coderabbitai
Copy link

coderabbitai bot commented Aug 29, 2025

Walkthrough

ReservedTimeInfo의 지속시간 표현을 Duration에서 long 초 단위로 변경하고, 무기한(-1/-1) 처리를 상수 기반으로 통일했습니다. MemberService는 toSeconds()를 사용하고, 역변환 시 INDEFINITE_SECONDS를 INDEFINITE_HOUR/MINUTE로 매핑합니다. 공통 상수 클래스(StatusReserveTimeConstants)를 신규 추가했습니다.

Changes

Cohort / File(s) Change Summary
상수 도입 (공통 시간/무기한 상수)
src/main/java/com/example/wini/global/common/constant/StatusReserveTimeConstants.java
시간 관련 상수 추가: SECONDS_PER_HOUR, SECONDS_PER_MINUTE, INDEFINITE_SECONDS, INDEFINITE_HOUR, INDEFINITE_MINUTE. 인스턴스화 방지.
DTO 지속시간 표현 변경
src/main/java/com/example/wini/domain/member/dto/common/ReservedTimeInfo.java
Duration 기반에서 long 초 기반으로 변경. toDuration()toSeconds(). 무기한은 상수(INDEFINITE_HOUR/MINUTE, INDEFINITE_SECONDS)로 판단/반환. 관련 import 정리.
서비스 로직 상수/초 단위 적용
src/main/java/com/example/wini/domain/member/service/MemberService.java
updateStatus에서 toSeconds() 사용. createReservedTimeInfo(long)에서 INDEFINITE_SECONDS 입력 시 (-1, -1)로 매핑. 상수 static import 추가. 외부 시그니처 변경 없음.

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: 응답
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10–15 minutes

Assessment against linked issues

Objective Addressed Explanation
상태 지속시간 미설정(무기한) 시 역변환 오류 해결 [#92]

Assessment against linked issues: Out-of-scope changes

(해당 없음)

Possibly related PRs

  • feat: 내 상태 수정 #45: ReservedTimeInfo의 Duration 기반 도입 및 MemberService.updateStatus에서의 사용 추가로, 본 PR의 초 단위 전환/상수화 변경과 직접적으로 연속된 변경입니다.

Suggested reviewers

  • ohhamma
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/89-healt-check

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.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbit in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbit 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:
    • @coderabbit gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbit read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

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

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbit help to get the list of available commands.

Other keywords and placeholders

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

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • 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.

@duol9 duol9 changed the title Feature/89 healt check fix: 상태 지속시간 미설정 시 역변환 안되는 오류 Aug 29, 2025
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

🧹 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 연산에서 hourlong이므로 상수도 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_SECONDSINDEFINITE_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이지만, 실제 DB status_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: 불필요한 오토박싱 제거: Longlong.

원시형 사용으로 가비지 최소화 및 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.

📥 Commits

Reviewing files that changed from the base of the PR and between 94bdb87 and 3f5b364.

📒 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) 원인을 정확히 해소합니다.

Comment on lines +19 to 24
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;
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

무기한(-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.

Suggested change
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.

Copy link
Member

@ohhamma ohhamma left a comment

Choose a reason for hiding this comment

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

오류 수정해주신 부분 확인했습니다!

@duol9 duol9 merged commit e5b9e0d into develop Aug 29, 2025
3 checks passed
@duol9 duol9 deleted the feature/89-healt-check branch August 29, 2025 13:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🐛 fix 버그 및 에러 픽스 🥇 P1 급하고 꼭 필요한 이슈

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🐛 상태 지속시간 미설정 시 역변환 안되는 오류

2 participants