-
Notifications
You must be signed in to change notification settings - Fork 2
[fix] 몽고디비에 UTC 시각으로 저장되지않는 문제를 해결한다 #922
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning
|
| Cohort / File(s) | Change Summary |
|---|---|
엔티티 시간 타입 변경backend/src/main/java/moadong/club/entity/ClubRecruitmentInformation.java |
recruitmentStart, recruitmentEnd 필드 타입을 LocalDateTime → Instant로 변경 및 Instant import 추가 |
요청 DTO 및 테스트 픽스처 업데이트backend/src/main/java/moadong/club/payload/request/ClubRecruitmentInfoUpdateRequest.java,backend/src/test/java/moadong/fixture/ClubRequestFixture.java |
ClubRecruitmentInfoUpdateRequest의 recruitmentStart/recruitmentEnd 타입을 Instant로 변경; 픽스처에서 Instant.now()/plus(…, ChronoUnit.DAYS) 사용 및 생성자 호출 인자 조정 (추가 List 인자 포함) |
응답 DTO 필드 분리backend/src/main/java/moadong/club/payload/dto/ClubDetailedResult.java |
레코드에서 recruitmentPeriod(String) 제거 후 recruitmentStart(String), recruitmentEnd(String) 추가; of(...) 빌더 로직을 start/end 개별 문자열로 변경 |
FCM 리포지토리 및 테스트 조정backend/src/main/java/moadong/fcm/repository/FcmTokenRepository.java,backend/src/test/java/moadong/fcm/service/FcmServiceTest.java |
void deleteFcmTokenByToken(String) 메서드 추가; 테스트 setUp에 fcmTokenRepository.deleteFcmTokenByToken("existing_token") 호출 추가 |
Estimated code review effort
🎯 3 (Moderate) | ⏱️ ~25 minutes
- 주의할 파일/포인트:
ClubDetailedResult.of(...)의 기본값 및 포맷 로직이 기존 동작을 올바르게 대체하는지 확인- MongoDB 직렬화/역직렬화(UTC 저장)와
Instant호환성 및 Spring Data 설정 검증 - 공개 API(레코드 필드명/타입) 변경에 따른 소비자 영향(직렬화된 JSON 스키마) 확인
- 테스트 픽스처에서 변경된 생성자 시그니처와 실제 레코드/생성자 일치 여부
- FcmTokenRepository에 추가된 삭제 메서드의 이름 규약 및 동작(삭제 쿼리)의 적절성 검토
Possibly related issues
- MOA-406 — MongoDB UTC 저장 문제 해결 목표와 연관:
LocalDateTime→Instant변경은 UTC 저장 문제 해결 목적과 맞닿아 있음. - [fix] MOA-406 몽고디비에 UTC 시각으로 저장되지않는 문제를 해결한다 #912 — (유사 검색 결과) 모집 필드의 시간 타입 변경 관련 문제와 개념적으로 관련됨.
Possibly related PRs
- [release] 모아동 BE ver 1.0.2 #329 — 동일한 모집 관련 엔티티/DTO들을 변경하는 PR로 코드 레벨 연관성 높음.
- [fix] 스케줄러는 db를 참조하여 모집현황을 갱신한다 #401 —
ClubRecruitmentInformation관련 start/end 처리 변경 이력이 있어 직접적인 관련 가능성 있음. - [Release] BE v1.0.6 배포 #675 —
ClubDetailedResult변경(필드/시그니처)과 겹치는 영역이 있어 관련성 있음.
Suggested labels
🔨 Refactor, 💾 BE, 📬 API
Suggested reviewers
- lepitaaar
- Zepelown
- PororoAndFriends
Pre-merge checks and finishing touches
❌ Failed checks (2 warnings)
| Check name | Status | Explanation | Resolution |
|---|---|---|---|
| Out of Scope Changes check | FCM 토큰 삭제 메서드 추가는 시간대 문제 해결과 직접적 관련이 없어 범위를 벗어난 변경입니다. | FCM 토큰 관련 변경사항(FcmTokenRepository.deleteFcmTokenByToken, FcmServiceTest 수정)을 별도의 PR로 분리하세요. | |
| Docstring Coverage | Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. | You can run @coderabbitai generate docstrings to improve docstring coverage. |
✅ Passed checks (3 passed)
| Check name | Status | Explanation |
|---|---|---|
| Description Check | ✅ Passed | Check skipped - CodeRabbit’s high-level summary is enabled. |
| Linked Issues check | ✅ Passed | 모든 코드 변경사항이 MOA-406의 목표와 일치합니다. LocalDateTime을 Instant로 변경하여 UTC 기준 저장을 보장하고, DTO 구조를 개선했습니다. |
| Title check | ✅ Passed | PR 제목이 변경사항의 핵심을 정확하게 반영하고 있습니다. MongoDB에 UTC 시각으로 저장되지 않는 문제를 해결한다는 내용이 PR의 주요 목표 및 변경사항과 일치합니다. |
✨ Finishing touches
- 📝 Generate docstrings
🧪 Generate unit tests (beta)
- Create PR with unit tests
- Post copyable unit tests in a comment
- Commit unit tests in branch
refactor/#912-db-utc-MOA-406
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.
Comment @coderabbitai help to get the list of available commands and usage tips.
Test Results75 tests 72 ✅ 20s ⏱️ Results for commit 806f92d. ♻️ This comment has been updated with latest results. |
There was a problem hiding this 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 (3)
backend/src/main/java/moadong/club/entity/ClubRecruitmentInformation.java (2)
10-11: 사용하지 않는 import를 제거하세요.
LocalDateTime이 더 이상 이 파일에서 사용되지 않으므로 import를 제거해야 합니다.다음 diff를 적용하여 사용하지 않는 import를 제거하세요:
import java.time.Instant; -import java.time.LocalDateTime; import java.time.ZoneId;
92-106: 타임존 변환 로직이 올바르게 구현되었습니다.
Instant를ZonedDateTime으로 변환하는 접근 방식이 정확합니다. DB에는 UTC로 저장하고, 조회 시 한국 시간으로 변환하여 반환하는 것이 올바른 패턴입니다.선택적 개선 사항:
ZoneId.of("Asia/Seoul")을 상수로 추출하면 반복 생성을 방지하고 가독성을 향상시킬 수 있습니다.+private static final ZoneId SEOUL_ZONE = ZoneId.of("Asia/Seoul"); + public ZonedDateTime getRecruitmentStart() { - ZoneId seoulZone = ZoneId.of("Asia/Seoul"); if (recruitmentStart == null) { return null; } - return recruitmentStart.atZone(seoulZone); + return recruitmentStart.atZone(SEOUL_ZONE); } public ZonedDateTime getRecruitmentEnd() { - ZoneId seoulZone = ZoneId.of("Asia/Seoul"); if (recruitmentEnd == null) { return null; } - return recruitmentEnd.atZone(seoulZone); + return recruitmentEnd.atZone(SEOUL_ZONE); }backend/src/main/java/moadong/club/payload/request/ClubRecruitmentInfoUpdateRequest.java (1)
3-4: 사용하지 않는 import를 제거하세요.
LocalDateTime이 더 이상 사용되지 않으므로 import를 제거해야 합니다.다음 diff를 적용하여 사용하지 않는 import를 제거하세요:
import java.time.Instant; -import java.time.LocalDateTime; import java.util.List;
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Jira integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
backend/src/main/java/moadong/club/entity/ClubRecruitmentInformation.java(2 hunks)backend/src/main/java/moadong/club/payload/dto/ClubDetailedResult.java(3 hunks)backend/src/main/java/moadong/club/payload/request/ClubRecruitmentInfoUpdateRequest.java(1 hunks)
🔇 Additional comments (4)
backend/src/main/java/moadong/club/entity/ClubRecruitmentInformation.java (1)
53-55: UTC 기반 저장을 위한 올바른 타입 변경입니다.
LocalDateTime에서Instant로의 변경은 MongoDB에 UTC 시각을 올바르게 저장하기 위한 적절한 해결책입니다.Instant는 타임존 정보를 포함하지 않고 UTC 기준의 시점을 표현하므로, 타임존 변환 오류를 방지할 수 있습니다.backend/src/main/java/moadong/club/payload/dto/ClubDetailedResult.java (3)
39-44: 날짜 포맷팅 로직이 정확합니다.기본값 "미정"을 사용하고 모집 기간이 있을 때 각각 포맷하는 로직이 올바르게 구현되었습니다. 엔티티의
getRecruitmentStart()와getRecruitmentEnd()가ZonedDateTime을 반환하므로 포맷터가 정상적으로 작동합니다.
69-70: 빌더 패턴이 올바르게 적용되었습니다.분리된
recruitmentStart와recruitmentEnd필드가 빌더에 정확하게 전달되고 있습니다.
24-25: Breaking API change confirmed:recruitmentPeriodreplaced with separaterecruitmentStartandrecruitmentEndfields.The field separation is correctly implemented in the DTO and properly propagated through
ClubDetailedResult.of()factory method. The backend correctly formats both fields with the pattern "yyyy.MM.dd HH:mm" and handles the "미정" (TBD) default when no recruitment period is set.This change affects the public API endpoint
GET /clubs/{clubId}(exposed viaClubProfileController.getClubDetail()). External API clients consuming this endpoint will need to update their code to use the two separate fields instead of the previous singlerecruitmentPeriodfield. Ensure frontend code and API documentation have been updated accordingly.
| Instant recruitmentStart, | ||
| Instant recruitmentEnd, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
cat -n backend/src/main/java/moadong/club/payload/request/ClubRecruitmentInfoUpdateRequest.java | head -30Repository: Moadong/moadong
Length of output: 551
🏁 Script executed:
rg -nP --type=java 'ClubRecruitmentInfoUpdateRequest' -A 5 -B 5Repository: Moadong/moadong
Length of output: 14068
🏁 Script executed:
rg -nP --type=java 'class ClubRecruitmentInformation' -A 40 | head -60Repository: Moadong/moadong
Length of output: 4038
🏁 Script executed:
sed -n '1,60p' backend/src/main/java/moadong/club/entity/ClubRecruitmentInformation.javaRepository: Moadong/moadong
Length of output: 1556
Remove the unused LocalDateTime import from the DTO.
The DTO's Instant type parameters correctly align with the entity's Instant fields, and all controller, service, and entity code properly handles the type. However, line 4 imports LocalDateTime but it's never used—remove this dead import for cleaner code.
🤖 Prompt for AI Agents
In
backend/src/main/java/moadong/club/payload/request/ClubRecruitmentInfoUpdateRequest.java
around lines 9-10, remove the unused import of java.time.LocalDateTime
(currently on line 4) since the DTO uses Instant; delete the dead import and
re-run your IDE's organize imports or build (mvn/gradle) to ensure no remaining
unused imports and that the file compiles.
클럽 모집정보 requestDTO와 엔티티를 localDateTime에서 변경함
f62fc9a to
87fb0d4
Compare
There was a problem hiding this 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
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Jira integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (3)
backend/src/main/java/moadong/club/entity/ClubRecruitmentInformation.java(2 hunks)backend/src/main/java/moadong/club/payload/dto/ClubDetailedResult.java(3 hunks)backend/src/main/java/moadong/club/payload/request/ClubRecruitmentInfoUpdateRequest.java(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- backend/src/main/java/moadong/club/payload/request/ClubRecruitmentInfoUpdateRequest.java
- backend/src/main/java/moadong/club/entity/ClubRecruitmentInformation.java
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: Zepelown
Repo: Moadong/moadong PR: 406
File: backend/src/main/java/moadong/club/entity/ClubApplicationQuestion.java:32-33
Timestamp: 2025-05-15T12:03:57.356Z
Learning: 엔티티 클래스는 요청/응답 객체(DTO)에 의존해서는 안 됩니다. 계층 간 의존성 문제를 방지하기 위해 엔티티와 DTO는 분리되어야 합니다. 예를 들어, `ClubApplicationQuestion` 엔티티가 `ClubApplicationRequest.Options`와 같은 요청 객체를 직접 참조하는 대신, 엔티티 패키지 내에 `QuestionOptions`와 같은 별도의 클래스를 정의하고 사용해야 합니다. 이렇게 하면 요청 객체 변경이 데이터베이스 스키마나 엔티티 계층에 영향을 미치지 않습니다.
🔇 Additional comments (3)
backend/src/main/java/moadong/club/payload/dto/ClubDetailedResult.java (3)
24-25: 모집 기간 필드 분리 변경 승인
recruitmentPeriod단일 문자열에서recruitmentStart와recruitmentEnd두 필드로 분리한 것은 프론트엔드에서 시간 보정 없이 직접 사용할 수 있게 해줍니다. PR 목표에 부합하는 변경입니다.
76-77: 빌더 호출 변경 적절함새로운 필드명
recruitmentStart와recruitmentEnd에 맞게 빌더 호출이 올바르게 업데이트되었습니다.
48-52: > Likely an incorrect or invalid review comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
backend/src/test/java/moadong/fixture/ClubRequestFixture.java (2)
8-10: 사용하지 않는 import를 정리하세요.
LocalDateTimeimport (line 9)는Instant로 리팩토링한 이후 더 이상 사용되지 않습니다. 코드 정리를 위해 제거하는 것이 좋습니다.다음과 같이 수정하세요:
import java.time.Instant; -import java.time.LocalDateTime; import java.time.temporal.ChronoUnit;
39-65: TODO 주석을 해결하세요.TODO 주석에 "시간 계산법을 LocalDateTime에서 Instant로 변경 후에 활성화할 것"이라고 명시되어 있는데,
defaultRequest()에서 이미Instant로 마이그레이션이 완료되었습니다. 주석 처리된createValidRequest()와createCustomRequest()메서드를 활성화하거나, 필요하지 않다면 완전히 제거하는 것을 권장합니다.이 픽스처 메서드들을 활성화하는 코드를 생성하거나, 관련 이슈를 생성하길 원하시나요?
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Jira integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (1)
backend/src/test/java/moadong/fixture/ClubRequestFixture.java(2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: Zepelown
Repo: Moadong/moadong PR: 406
File: backend/src/main/java/moadong/club/entity/ClubApplicationQuestion.java:32-33
Timestamp: 2025-05-15T12:03:57.356Z
Learning: 엔티티 클래스는 요청/응답 객체(DTO)에 의존해서는 안 됩니다. 계층 간 의존성 문제를 방지하기 위해 엔티티와 DTO는 분리되어야 합니다. 예를 들어, `ClubApplicationQuestion` 엔티티가 `ClubApplicationRequest.Options`와 같은 요청 객체를 직접 참조하는 대신, 엔티티 패키지 내에 `QuestionOptions`와 같은 별도의 클래스를 정의하고 사용해야 합니다. 이렇게 하면 요청 객체 변경이 데이터베이스 스키마나 엔티티 계층에 영향을 미치지 않습니다.
🔇 Additional comments (1)
backend/src/test/java/moadong/fixture/ClubRequestFixture.java (1)
31-32: UTC 타임스탬프로의 변경이 올바릅니다!
LocalDateTime에서Instant로의 변경은 PR 목표와 정확히 일치합니다.Instant는 UTC 기준의 시점을 나타내므로 타임존 정보 손실 문제를 해결합니다.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
backend/src/main/java/moadong/fcm/repository/FcmTokenRepository.java (1)
10-11: PR 목표와의 불일치를 확인하세요.이 변경사항은 PR의 주요 목표인 "MongoDB UTC 시각 저장 문제 해결"과 직접적인 관련이 없어 보입니다. FCM 토큰 삭제 메서드 추가는 테스트 격리를 위한 유틸리티 기능이지만, PR 설명에서 언급한
LocalDateTime → Instant변환 작업과는 무관합니다.메서드 자체는 Spring Data MongoDB 네이밍 컨벤션을 올바르게 따르고 있으며 기능적으로 문제없지만, 이러한 부수적인 변경은 별도의 PR로 분리하는 것이 변경 이력 관리에 더 좋습니다.
참고: 11번 라인의 불필요한 빈 줄을 제거할 수 있습니다.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Disabled knowledge base sources:
- Jira integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
backend/src/main/java/moadong/fcm/repository/FcmTokenRepository.java(1 hunks)backend/src/test/java/moadong/fcm/service/FcmServiceTest.java(1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: Zepelown
Repo: Moadong/moadong PR: 406
File: backend/src/main/java/moadong/club/entity/ClubApplicationQuestion.java:32-33
Timestamp: 2025-05-15T12:03:57.356Z
Learning: 엔티티 클래스는 요청/응답 객체(DTO)에 의존해서는 안 됩니다. 계층 간 의존성 문제를 방지하기 위해 엔티티와 DTO는 분리되어야 합니다. 예를 들어, `ClubApplicationQuestion` 엔티티가 `ClubApplicationRequest.Options`와 같은 요청 객체를 직접 참조하는 대신, 엔티티 패키지 내에 `QuestionOptions`와 같은 별도의 클래스를 정의하고 사용해야 합니다. 이렇게 하면 요청 객체 변경이 데이터베이스 스키마나 엔티티 계층에 영향을 미치지 않습니다.
⏰ 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: test
🔇 Additional comments (1)
backend/src/test/java/moadong/fcm/service/FcmServiceTest.java (1)
69-69: PR 목표와의 불일치를 확인하세요.
deleteFcmTokenByToken호출을 통한 테스트 격리는 좋은 관행이지만, 이 변경사항은 PR의 명시된 목표인 "MongoDB UTC 시각 저장 문제 해결" 및LocalDateTime → Instant변환 작업과 무관합니다.테스트 클린업 로직 자체는 올바르게 구현되어 있으며, 각 테스트가 자체 픽스처를 생성하므로 (
saveFcmToken_whenExistingToken_thenUpdateTimestamp테스트는 103번 라인에서 자체적으로 토큰을 생성) 테스트 격리에 문제가 없습니다.그러나 이러한 부수적인 개선사항은 별도의 PR로 분리하여 변경 이력을 명확하게 유지하는 것을 권장합니다.
lepitaaar
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
기존 로컬타임을 Instant로 변경하신거 좋네요 나중에 트러블슈팅 경험으로 기록해놔도 좋을꺼같아요!!!
#️⃣연관된 이슈
📝작업 내용
(자세한 내용은 "모아동 노션>백엔드자료실>학습내용"에 있습니다)
1. 근본적인 원인
즉, LocalDateTime 사용으로 인해 타임존 정보가 손실되었고,
저장 및 조회 시점에서 반복된 변환으로 인해 시각이 계속 왜곡되는 구조였습니다.
2. 해결
중점적으로 리뷰받고 싶은 부분(선택)
논의하고 싶은 부분(선택)
🫡 참고사항
Summary by CodeRabbit
개선사항
기타
✏️ Tip: You can customize this high-level summary in your review settings.