Skip to content

[ENHANCEMENT] 타임존 처리 KST로 통일#115

Merged
fervovita merged 4 commits into
devfrom
refactor/#111-timezone
Jul 10, 2026
Merged

[ENHANCEMENT] 타임존 처리 KST로 통일#115
fervovita merged 4 commits into
devfrom
refactor/#111-timezone

Conversation

@fervovita

@fervovita fervovita commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

🚀 Related issue

Closes #111

#️⃣ Summary

  • 타임존 처리를 KST로 통일하고 흩어진 ZoneId를 제거했습니다.

🔧 Changes

  • JVM 타임존 KST 고정
  • 흩어진 ZONE_KST 상수·now(ZONE_KST) 제거
  • @JsonFormattimezone="Asia/Seoul" 속성 제거
  • 서버·DB·JVM 타임존을 KST로 통일

📸 Test Evidence

  • swagger나 postman 결과를 캡쳐하여 첨부

💬 Reviewer Notes

  • BackendApplicationTimeZone.setDefault는 Jib TZ와 중복이지만 의도적으로 유지했습니다.
    Jib TZ는 컨테이너 실행 시에만 적용되어, 로컬 실행이나 나중에 배포 도구가 바뀔 때 TZ 설정이 유실되면 조용히 UTC로 돌아갈 수 있는 문제점이 있어 실행 환경과 무관하게 JVM이 KST를 보장하도록 했습니다.

  • @Scheduled(zone="Asia/Seoul")은 의도적으로 유지했습니다.
    다른 ZoneId 명시와 달리 cron 해석 존을 정하는 실제 동작 속성입니다. 스케줄러가 UTC를 기준으로 돌면 크리티컬한 문제라, 명시적으로 남겼습니다.

Summary by CodeRabbit

  • New Features

    • 알림 발송이 한곳에서 일관된 유형 기반 방식으로 정리되어, 다양한 회원가입/정산/마감/매칭 알림이 더 안정적으로 처리됩니다.
    • 디자이너 가입 검토 알림에 포트폴리오 확인 안내와 어드민 바로가기 링크가 추가되었습니다.
    • 커미션 매칭 완료 알림이 새로 제공되어 강사와 디자이너에게 더 빠르게 안내됩니다.
  • Bug Fixes

    • 날짜/시간 표시와 처리 기준이 정리되어, 일부 응답과 알림의 시간대 표시가 더 일관되게 동작합니다.

@fervovita fervovita self-assigned this Jul 9, 2026
@fervovita
fervovita requested a review from Jong0128 as a code owner July 9, 2026 13:10
@fervovita
fervovita changed the base branch from dev to refactor/#94-notification-event July 9, 2026 13:10
@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

알림 발송 방식을 메일 직접 전송에서 NotificationType 기반 NotificationOutbox 저장 방식으로 전면 전환했으며, 신규 CommissionMatchedEvent/Notifier를 추가했다. 또한 JVM 기본 타임존을 Asia/Seoul로 설정하고, 서비스/응답 DTO에 산재된 명시적 Asia/Seoul ZoneId/@jsonformat timezone 지정을 제거했다.

Changes

Notification Outbox 전환

Layer / File(s) Summary
NotificationType/Outbox 인프라
global/notification/NotificationType.java, global/notification/NotificationOutbox.java, global/notification/EmailSender.java, global/notification/NotificationOutboxRepository.java, global/notification/NotificationOutboxScheduler.java, global/notification/OutboxStatus.java
NotificationType enum 신설, NotificationOutbox.create가 subject/template 대신 NotificationType을 인자로 받도록 변경, EmailSender.sendAsync 시그니처 변경, 관련 클래스들이 global.email에서 global.notification 패키지로 이동.
디자이너 가입 알림 전환
auth/event/DesignerSignedUpEvent.java, auth/service/DesignerAuthService.java, auth/notification/DesignerSignupMailer.java(삭제), auth/notification/DesignerSignupNotifier.java, auth/notification/EmailVerificationMailer.java, templates/email/designer-signup-notification.html
이벤트 필드가 designerId/hasPortfolio/mailScheduledAt로 재구성되고, DesignerSignupMailer 삭제 후 DesignerSignupNotifier가 outbox에 저장하도록 변경, 이메일 템플릿에서 포트폴리오 링크 대신 Swagger 링크 안내.
입금 알림 outbox 전환
payment/event/DepositNotifiedEvent.java, payment/notification/DepositMailer.java(삭제), payment/notification/DepositNotifier.java, payment/service/PaymentService.java, templates/email/deposit-notification.html
DepositNotifiedEvent에 mailScheduledAt 추가, DepositMailer 삭제 후 DepositNotifier가 outbox에 저장하도록 전환.
커미션 매칭 이벤트 재정의
commission/core/event/CommissionMatchedEvent.java, commission/application/facade/DesignerApplicationFacade.java, commission/core/notification/CommissionMatchedNotifier.java
ApplicationDeadlineClosedEvent 대신 CommissionMatchedEvent를 신규 정의·발행하고, CommissionMatchedNotifier가 인스트럭터/디자이너 알림을 outbox에 저장.
커미션 라이프사이클 Notifier 전환
commission/core/notification/{AllFirstDraftsSubmittedNotifier,ApplicationDeadlineClosedNotifier,CommissionCompletedNotifier,DraftSelectedNotifier,FinalDeadlineClosedNotifier,FirstDraftDeadlineClosedNotifier,PayoutRequestedNotifier,RevisionRequestedNotifier,RevisionSubmittedNotifier}.java
각 Notifier가 하드코딩된 제목/템플릿 문자열 대신 NotificationType 상수를 전달하도록 일괄 변경, Slf4j 로깅 제거.

Estimated code review effort: 4 (Complex) | ~60 minutes

KST 타임존 통일

Layer / File(s) Summary
JVM 기본 타임존 설정
BackendApplication.java
main 메서드에서 TimeZone.setDefault(Asia/Seoul)를 호출하도록 추가.
서비스/Facade 명시적 ZoneId 제거
commission/core/service/CommissionDeadlineService.java, commission/draft/facade/{DesignerDraftFacade,InstructorDraftFacade}.java, commission/revision/facade/{DesignerRevisionFacade,InstructorRevisionFacade}.java
ZONE_KST 상수 및 ZoneId import 제거, LocalDateTime.now(ZONE_KST)를 LocalDateTime.now()로 변경.
응답 DTO @JsonFormat timezone 제거
commission/core/dto/response/CommissionCreateResponse.java, commission/draft/dto/response/{DraftSelectResponse,DraftSubmitResponse}.java, payment/dto/response/DepositNotifyResponse.java, global/apipayload/response/ApiResponse.java
@JsonFormat에서 timezone="Asia/Seoul" 속성을 제거하고 pattern/shape만 유지.

Estimated code review effort: 2 (Simple) | ~15 minutes

Possibly related PRs

  • Ditda-Official/Ditda-Backend#16: DesignerSignedUpEvent와 디자이너 가입 알림 흐름(DesignerSignupMailer→outbox 전환)이 해당 PR에서 도입된 가입 기능을 직접 리팩터링.
  • Ditda-Official/Ditda-Backend#34: DepositNotifiedEvent/DepositNotifier/DepositMailer 관련 최초 입금 알림 구현을 outbox 방식으로 직접 전환.
  • Ditda-Official/Ditda-Backend#95: DesignerApplicationFacade의 매칭 이벤트 발행/매핑 로직(ApplicationDeadlineClosedEvent↔CommissionMatchedEvent)을 직접 다룸.

Suggested reviewers: Jong0128

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning 타임존 통일과 무관한 알림·이메일·이벤트 리팩터링이 대거 포함되어 있습니다. 타임존 관련 변경만 남기고, notification·mail·event 계약 변경은 별도 PR로 분리하세요.
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% 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
Linked Issues check ✅ Passed KST 기본 타임존 고정과 분산된 ZoneId 및 timezone 설정 제거가 이슈 목적과 일치합니다.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR의 핵심 변경인 KST 기준 시간대 통일과 관련된 내용을 정확하게 요약합니다.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/#111-timezone

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/ditda/backend/domain/auth/service/DesignerAuthService.java (1)

78-83: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Designer ID에는 designer.getId()를 전달해야 합니다.

Line 79의 user.getId()는 이벤트/템플릿에서 designerId로 소비됩니다. 관리자 메일도 디자이너 ID로 포트폴리오 조회를 안내하므로, User PK가 전달되면 조회가 실패할 수 있습니다.

수정 제안
 		eventPublisher.publishEvent(new DesignerSignedUpEvent(
-			user.getId(),
+			designer.getId(),
 			user.getName(),
 			user.getEmail(),
 			!portfolioKeys.isEmpty(),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/ditda/backend/domain/auth/service/DesignerAuthService.java`
around lines 78 - 83, The DesignerSignedUpEvent is currently being published
with user.getId(), but this value is consumed as designerId in downstream event
handling and email/template logic. Update DesignerAuthService to pass
designer.getId() into the DesignerSignedUpEvent constructor, keeping the other
fields unchanged, so portfolio lookup and admin guidance resolve against the
correct designer identifier.
🧹 Nitpick comments (1)
src/main/java/ditda/backend/domain/payment/notification/DepositNotifier.java (1)

3-47: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

@EventListener 전환은 outbox 패턴에 적절합니다.

@TransactionalEventListener(AFTER_COMMIT)에서 @EventListener로의 변경은 동일 트랜잭션 내에서 outbox 레코드를 저장하게 하여, 비즈니스 상태 변경과 알림 등록의 원자성을 보장합니다. try-catch/로깅 제거도 scheduler에 위임하는 구조와 일관됩니다.

DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")이 호출마다 새 인스턴스를 생성합니다. private static final 상수로 추출을 권장합니다.

♻️ 제안: DateTimeFormatter 상수화
+	private static final DateTimeFormatter NOTIFIED_AT_FORMATTER =
+		DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
+
 	// 어드민 입금 확인 메일 발송
 	private void registerAdminDepositCheck(DepositNotifiedEvent event, LocalDateTime mailScheduledAt) {
 		outboxRepository.save(NotificationOutbox.create(
 			adminProperties.getNotificationEmail(),
 			NotificationType.DEPOSIT_CONFIRM_REQUEST_ADMIN,
 			Map.of(
 				"commissionId", event.commissionId(),
 				"title", event.commissionTitle(),
 				"instructorName", event.instructorName(),
 				"depositorName", event.depositorName(),
 				"amount", event.amount(),
-				"notifiedAt", event.notifiedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))
+				"notifiedAt", event.notifiedAt().format(NOTIFIED_AT_FORMATTER)
 			),
 			mailScheduledAt
 		));
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/ditda/backend/domain/payment/notification/DepositNotifier.java`
around lines 3 - 47, `DepositNotifier.onDepositNotified` and
`registerAdminDepositCheck` are fine functionally, but the timestamp formatter
is recreated on every event. Extract the
`DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")` used for `notifiedAt` into a
`private static final` constant in `DepositNotifier` and reuse it in the
`Map.of(...)` payload to avoid repeated allocations and keep formatting
centralized.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/main/java/ditda/backend/domain/commission/core/service/CommissionDeadlineService.java`:
- Line 33: `CommissionDeadlineService`에서 `LocalDate.now()`가 JVM 기본 타임존을 따라 테스트에서
날짜가 흔들리는 문제를 고쳐야 합니다. `get...`/마감 조회 로직에서 현재 날짜를 직접 생성하는 부분을 `Clock` 또는 고정된
`ZoneId` 기반으로 주입받아 사용하도록 바꾸고, `@SpringBootTest`와 관련 단위 테스트 부트스트랩에서도 `Asia/Seoul`
타임존이 고정되도록 설정해 `CommissionDeadlineService`의 조회 결과가 CI에서 일관되게 나오게 해 주세요.

In `@src/main/resources/templates/email/designer-signup-notification.html`:
- Around line 42-46: The designer signup email template currently hardcodes the
Swagger URL, which can send the wrong link outside production. Update the link
in designer-signup-notification.html to use the existing swagger.server-url
value as a template variable and bind it with th:href instead of a fixed href,
so the button resolves correctly across environments.

---

Outside diff comments:
In `@src/main/java/ditda/backend/domain/auth/service/DesignerAuthService.java`:
- Around line 78-83: The DesignerSignedUpEvent is currently being published with
user.getId(), but this value is consumed as designerId in downstream event
handling and email/template logic. Update DesignerAuthService to pass
designer.getId() into the DesignerSignedUpEvent constructor, keeping the other
fields unchanged, so portfolio lookup and admin guidance resolve against the
correct designer identifier.

---

Nitpick comments:
In
`@src/main/java/ditda/backend/domain/payment/notification/DepositNotifier.java`:
- Around line 3-47: `DepositNotifier.onDepositNotified` and
`registerAdminDepositCheck` are fine functionally, but the timestamp formatter
is recreated on every event. Extract the
`DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")` used for `notifiedAt` into a
`private static final` constant in `DepositNotifier` and reuse it in the
`Map.of(...)` payload to avoid repeated allocations and keep formatting
centralized.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: 27dea4de-e96e-403b-a00c-f390f2ebeea4

📥 Commits

Reviewing files that changed from the base of the PR and between 31c7679 and 6a3f93a.

📒 Files selected for processing (40)
  • src/main/java/ditda/backend/BackendApplication.java
  • src/main/java/ditda/backend/domain/auth/event/DesignerSignedUpEvent.java
  • src/main/java/ditda/backend/domain/auth/notification/DesignerSignupMailer.java
  • src/main/java/ditda/backend/domain/auth/notification/DesignerSignupNotifier.java
  • src/main/java/ditda/backend/domain/auth/notification/EmailVerificationMailer.java
  • src/main/java/ditda/backend/domain/auth/service/DesignerAuthService.java
  • src/main/java/ditda/backend/domain/commission/application/facade/DesignerApplicationFacade.java
  • src/main/java/ditda/backend/domain/commission/core/dto/response/CommissionCreateResponse.java
  • src/main/java/ditda/backend/domain/commission/core/event/CommissionMatchedEvent.java
  • src/main/java/ditda/backend/domain/commission/core/notification/AllFirstDraftsSubmittedNotifier.java
  • src/main/java/ditda/backend/domain/commission/core/notification/ApplicationDeadlineClosedNotifier.java
  • src/main/java/ditda/backend/domain/commission/core/notification/CommissionCompletedNotifier.java
  • src/main/java/ditda/backend/domain/commission/core/notification/CommissionMatchedNotifier.java
  • src/main/java/ditda/backend/domain/commission/core/notification/DraftSelectedNotifier.java
  • src/main/java/ditda/backend/domain/commission/core/notification/FinalDeadlineClosedNotifier.java
  • src/main/java/ditda/backend/domain/commission/core/notification/FirstDraftDeadlineClosedNotifier.java
  • src/main/java/ditda/backend/domain/commission/core/notification/PayoutRequestedNotifier.java
  • src/main/java/ditda/backend/domain/commission/core/notification/RevisionRequestedNotifier.java
  • src/main/java/ditda/backend/domain/commission/core/notification/RevisionSubmittedNotifier.java
  • src/main/java/ditda/backend/domain/commission/core/service/CommissionDeadlineService.java
  • src/main/java/ditda/backend/domain/commission/draft/dto/response/DraftSelectResponse.java
  • src/main/java/ditda/backend/domain/commission/draft/dto/response/DraftSubmitResponse.java
  • src/main/java/ditda/backend/domain/commission/draft/facade/DesignerDraftFacade.java
  • src/main/java/ditda/backend/domain/commission/draft/facade/InstructorDraftFacade.java
  • src/main/java/ditda/backend/domain/commission/revision/facade/DesignerRevisionFacade.java
  • src/main/java/ditda/backend/domain/commission/revision/facade/InstructorRevisionFacade.java
  • src/main/java/ditda/backend/domain/payment/dto/response/DepositNotifyResponse.java
  • src/main/java/ditda/backend/domain/payment/event/DepositNotifiedEvent.java
  • src/main/java/ditda/backend/domain/payment/notification/DepositMailer.java
  • src/main/java/ditda/backend/domain/payment/notification/DepositNotifier.java
  • src/main/java/ditda/backend/domain/payment/service/PaymentService.java
  • src/main/java/ditda/backend/global/apipayload/response/ApiResponse.java
  • src/main/java/ditda/backend/global/notification/EmailSender.java
  • src/main/java/ditda/backend/global/notification/NotificationOutbox.java
  • src/main/java/ditda/backend/global/notification/NotificationOutboxRepository.java
  • src/main/java/ditda/backend/global/notification/NotificationOutboxScheduler.java
  • src/main/java/ditda/backend/global/notification/NotificationType.java
  • src/main/java/ditda/backend/global/notification/OutboxStatus.java
  • src/main/resources/templates/email/deposit-notification.html
  • src/main/resources/templates/email/designer-signup-notification.html
💤 Files with no reviewable changes (2)
  • src/main/java/ditda/backend/domain/auth/notification/DesignerSignupMailer.java
  • src/main/java/ditda/backend/domain/payment/notification/DepositMailer.java

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/ditda/backend/domain/auth/service/DesignerAuthService.java (1)

78-83: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Designer ID에는 designer.getId()를 전달해야 합니다.

Line 79의 user.getId()는 이벤트/템플릿에서 designerId로 소비됩니다. 관리자 메일도 디자이너 ID로 포트폴리오 조회를 안내하므로, User PK가 전달되면 조회가 실패할 수 있습니다.

수정 제안
 		eventPublisher.publishEvent(new DesignerSignedUpEvent(
-			user.getId(),
+			designer.getId(),
 			user.getName(),
 			user.getEmail(),
 			!portfolioKeys.isEmpty(),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/ditda/backend/domain/auth/service/DesignerAuthService.java`
around lines 78 - 83, The DesignerSignedUpEvent is currently being published
with user.getId(), but this value is consumed as designerId in downstream event
handling and email/template logic. Update DesignerAuthService to pass
designer.getId() into the DesignerSignedUpEvent constructor, keeping the other
fields unchanged, so portfolio lookup and admin guidance resolve against the
correct designer identifier.
🧹 Nitpick comments (1)
src/main/java/ditda/backend/domain/payment/notification/DepositNotifier.java (1)

3-47: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

@EventListener 전환은 outbox 패턴에 적절합니다.

@TransactionalEventListener(AFTER_COMMIT)에서 @EventListener로의 변경은 동일 트랜잭션 내에서 outbox 레코드를 저장하게 하여, 비즈니스 상태 변경과 알림 등록의 원자성을 보장합니다. try-catch/로깅 제거도 scheduler에 위임하는 구조와 일관됩니다.

DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")이 호출마다 새 인스턴스를 생성합니다. private static final 상수로 추출을 권장합니다.

♻️ 제안: DateTimeFormatter 상수화
+	private static final DateTimeFormatter NOTIFIED_AT_FORMATTER =
+		DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
+
 	// 어드민 입금 확인 메일 발송
 	private void registerAdminDepositCheck(DepositNotifiedEvent event, LocalDateTime mailScheduledAt) {
 		outboxRepository.save(NotificationOutbox.create(
 			adminProperties.getNotificationEmail(),
 			NotificationType.DEPOSIT_CONFIRM_REQUEST_ADMIN,
 			Map.of(
 				"commissionId", event.commissionId(),
 				"title", event.commissionTitle(),
 				"instructorName", event.instructorName(),
 				"depositorName", event.depositorName(),
 				"amount", event.amount(),
-				"notifiedAt", event.notifiedAt().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))
+				"notifiedAt", event.notifiedAt().format(NOTIFIED_AT_FORMATTER)
 			),
 			mailScheduledAt
 		));
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/ditda/backend/domain/payment/notification/DepositNotifier.java`
around lines 3 - 47, `DepositNotifier.onDepositNotified` and
`registerAdminDepositCheck` are fine functionally, but the timestamp formatter
is recreated on every event. Extract the
`DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")` used for `notifiedAt` into a
`private static final` constant in `DepositNotifier` and reuse it in the
`Map.of(...)` payload to avoid repeated allocations and keep formatting
centralized.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@src/main/java/ditda/backend/domain/commission/core/service/CommissionDeadlineService.java`:
- Line 33: `CommissionDeadlineService`에서 `LocalDate.now()`가 JVM 기본 타임존을 따라 테스트에서
날짜가 흔들리는 문제를 고쳐야 합니다. `get...`/마감 조회 로직에서 현재 날짜를 직접 생성하는 부분을 `Clock` 또는 고정된
`ZoneId` 기반으로 주입받아 사용하도록 바꾸고, `@SpringBootTest`와 관련 단위 테스트 부트스트랩에서도 `Asia/Seoul`
타임존이 고정되도록 설정해 `CommissionDeadlineService`의 조회 결과가 CI에서 일관되게 나오게 해 주세요.

In `@src/main/resources/templates/email/designer-signup-notification.html`:
- Around line 42-46: The designer signup email template currently hardcodes the
Swagger URL, which can send the wrong link outside production. Update the link
in designer-signup-notification.html to use the existing swagger.server-url
value as a template variable and bind it with th:href instead of a fixed href,
so the button resolves correctly across environments.

---

Outside diff comments:
In `@src/main/java/ditda/backend/domain/auth/service/DesignerAuthService.java`:
- Around line 78-83: The DesignerSignedUpEvent is currently being published with
user.getId(), but this value is consumed as designerId in downstream event
handling and email/template logic. Update DesignerAuthService to pass
designer.getId() into the DesignerSignedUpEvent constructor, keeping the other
fields unchanged, so portfolio lookup and admin guidance resolve against the
correct designer identifier.

---

Nitpick comments:
In
`@src/main/java/ditda/backend/domain/payment/notification/DepositNotifier.java`:
- Around line 3-47: `DepositNotifier.onDepositNotified` and
`registerAdminDepositCheck` are fine functionally, but the timestamp formatter
is recreated on every event. Extract the
`DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")` used for `notifiedAt` into a
`private static final` constant in `DepositNotifier` and reuse it in the
`Map.of(...)` payload to avoid repeated allocations and keep formatting
centralized.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro Plus

Run ID: 27dea4de-e96e-403b-a00c-f390f2ebeea4

📥 Commits

Reviewing files that changed from the base of the PR and between 31c7679 and 6a3f93a.

📒 Files selected for processing (40)
  • src/main/java/ditda/backend/BackendApplication.java
  • src/main/java/ditda/backend/domain/auth/event/DesignerSignedUpEvent.java
  • src/main/java/ditda/backend/domain/auth/notification/DesignerSignupMailer.java
  • src/main/java/ditda/backend/domain/auth/notification/DesignerSignupNotifier.java
  • src/main/java/ditda/backend/domain/auth/notification/EmailVerificationMailer.java
  • src/main/java/ditda/backend/domain/auth/service/DesignerAuthService.java
  • src/main/java/ditda/backend/domain/commission/application/facade/DesignerApplicationFacade.java
  • src/main/java/ditda/backend/domain/commission/core/dto/response/CommissionCreateResponse.java
  • src/main/java/ditda/backend/domain/commission/core/event/CommissionMatchedEvent.java
  • src/main/java/ditda/backend/domain/commission/core/notification/AllFirstDraftsSubmittedNotifier.java
  • src/main/java/ditda/backend/domain/commission/core/notification/ApplicationDeadlineClosedNotifier.java
  • src/main/java/ditda/backend/domain/commission/core/notification/CommissionCompletedNotifier.java
  • src/main/java/ditda/backend/domain/commission/core/notification/CommissionMatchedNotifier.java
  • src/main/java/ditda/backend/domain/commission/core/notification/DraftSelectedNotifier.java
  • src/main/java/ditda/backend/domain/commission/core/notification/FinalDeadlineClosedNotifier.java
  • src/main/java/ditda/backend/domain/commission/core/notification/FirstDraftDeadlineClosedNotifier.java
  • src/main/java/ditda/backend/domain/commission/core/notification/PayoutRequestedNotifier.java
  • src/main/java/ditda/backend/domain/commission/core/notification/RevisionRequestedNotifier.java
  • src/main/java/ditda/backend/domain/commission/core/notification/RevisionSubmittedNotifier.java
  • src/main/java/ditda/backend/domain/commission/core/service/CommissionDeadlineService.java
  • src/main/java/ditda/backend/domain/commission/draft/dto/response/DraftSelectResponse.java
  • src/main/java/ditda/backend/domain/commission/draft/dto/response/DraftSubmitResponse.java
  • src/main/java/ditda/backend/domain/commission/draft/facade/DesignerDraftFacade.java
  • src/main/java/ditda/backend/domain/commission/draft/facade/InstructorDraftFacade.java
  • src/main/java/ditda/backend/domain/commission/revision/facade/DesignerRevisionFacade.java
  • src/main/java/ditda/backend/domain/commission/revision/facade/InstructorRevisionFacade.java
  • src/main/java/ditda/backend/domain/payment/dto/response/DepositNotifyResponse.java
  • src/main/java/ditda/backend/domain/payment/event/DepositNotifiedEvent.java
  • src/main/java/ditda/backend/domain/payment/notification/DepositMailer.java
  • src/main/java/ditda/backend/domain/payment/notification/DepositNotifier.java
  • src/main/java/ditda/backend/domain/payment/service/PaymentService.java
  • src/main/java/ditda/backend/global/apipayload/response/ApiResponse.java
  • src/main/java/ditda/backend/global/notification/EmailSender.java
  • src/main/java/ditda/backend/global/notification/NotificationOutbox.java
  • src/main/java/ditda/backend/global/notification/NotificationOutboxRepository.java
  • src/main/java/ditda/backend/global/notification/NotificationOutboxScheduler.java
  • src/main/java/ditda/backend/global/notification/NotificationType.java
  • src/main/java/ditda/backend/global/notification/OutboxStatus.java
  • src/main/resources/templates/email/deposit-notification.html
  • src/main/resources/templates/email/designer-signup-notification.html
💤 Files with no reviewable changes (2)
  • src/main/java/ditda/backend/domain/auth/notification/DesignerSignupMailer.java
  • src/main/java/ditda/backend/domain/payment/notification/DepositMailer.java
🛑 Comments failed to post (2)
src/main/java/ditda/backend/domain/commission/core/service/CommissionDeadlineService.java (1)

33-33: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: 테스트 환경에서 TimeZone 설정 여부 확인

# 테스트 설정 클래스에서 TimeZone.setDefault 호출 여부 검색
rg -rn --type=java 'TimeZone\.setDefault' -g '**/test/**' -g '**/*Test*' -g '**/*Spec*'

# `@SpringBootTest` 또는 테스트 설정 클래스에서 타임존 관련 설정 검색
rg -rn --type=java 'TimeZone|ZoneId|Asia/Seoul' -g '**/test/**' -g '**/*Test*' -g '**/*Spec*'

Repository: Ditda-Official/Ditda-Backend

Length of output: 166


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Relevant files =="
git ls-files | rg '(^|/)(src/test|test|tests|spec|.*Test.*|.*Spec.*|BackendApplication\.java|CommissionDeadlineService\.java)$'

echo
echo "== Search for timezone setup in main/test code =="
rg -n --hidden --glob '!**/target/**' --glob '!**/build/**' --glob '!**/out/**' 'TimeZone\.setDefault|ZoneId|Asia/Seoul|UTC' src test .github || true

echo
echo "== CommissionDeadlineService.java =="
sed -n '1,120p' src/main/java/ditda/backend/domain/commission/core/service/CommissionDeadlineService.java

echo
echo "== BackendApplication.java =="
sed -n '1,160p' src/main/java/ditda/backend/BackendApplication.java

echo
echo "== Test files containing `@SpringBootTest` or test configuration =="
rg -n --hidden --glob '!**/target/**' --glob '!**/build/**' --glob '!**/out/**' '`@SpringBootTest`|`@TestConfiguration`|`@BeforeAll`|`@PostConstruct`' src/test test || true

Repository: Ditda-Official/Ditda-Backend

Length of output: 5687


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== BackendApplicationTests.java =="
sed -n '1,220p' src/test/java/ditda/backend/BackendApplicationTests.java

echo
echo "== Test resources =="
git ls-files src/test/resources || true
for f in $(git ls-files 'src/test/resources/**' 2>/dev/null || true); do
  echo
  echo "== $f =="
  sed -n '1,220p' "$f"
done

echo
echo "== Search for any timezone test bootstrap =="
rg -n --hidden --glob 'src/test/java/**' --glob 'src/test/resources/**' 'TimeZone\.setDefault|ZoneId|Asia/Seoul|UTC|Clock\.fixed|now\(' src/test/java src/test/resources || true

Repository: Ditda-Official/Ditda-Backend

Length of output: 2081


테스트 부트스트랩에서도 타임존을 고정해 주세요 LocalDate.now()는 JVM 기본 타임존을 따르므로, @SpringBootTest/단위 테스트에서 Asia/Seoul로 고정하지 않으면 CI에서 날짜 경계가 달라져 마감 조회 결과가 흔들릴 수 있습니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/main/java/ditda/backend/domain/commission/core/service/CommissionDeadlineService.java`
at line 33, `CommissionDeadlineService`에서 `LocalDate.now()`가 JVM 기본 타임존을 따라
테스트에서 날짜가 흔들리는 문제를 고쳐야 합니다. `get...`/마감 조회 로직에서 현재 날짜를 직접 생성하는 부분을 `Clock` 또는
고정된 `ZoneId` 기반으로 주입받아 사용하도록 바꾸고, `@SpringBootTest`와 관련 단위 테스트 부트스트랩에서도
`Asia/Seoul` 타임존이 고정되도록 설정해 `CommissionDeadlineService`의 조회 결과가 CI에서 일관되게 나오게 해
주세요.
src/main/resources/templates/email/designer-signup-notification.html (1)

42-46: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# 기존에 재사용 가능한 admin/swagger/base URL 설정이 있는지 확인합니다.
rg -n -C2 'swagger-ui|adminSwaggerUrl|api\.ditda\.kr|class AdminProperties|record AdminProperties|notificationEmail' .

Repository: Ditda-Official/Ditda-Backend

Length of output: 5620


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- file outline: relevant config and email files ---'
ast-grep outline src/main/java/ditda/backend/global/config/AdminProperties.java --view expanded || true
ast-grep outline src/main/resources/application.yaml --view expanded || true
ast-grep outline src/main/resources/application-prod.yaml --view expanded || true
ast-grep outline src/main/resources/templates/email/designer-signup-notification.html --view expanded || true
ast-grep outline src/main/resources/templates/email/admin-payout-request.html --view expanded || true

echo '--- search email rendering / template variable usage ---'
rg -n -C2 'process\(|TemplateEngine|Context|setVariable|thymeleaf|designer-signup-notification|admin-payout-request|notificationEmail|swagger\.server-url|server-url' src/main/java src/main/resources

Repository: Ditda-Official/Ditda-Backend

Length of output: 19701


src/main/resources/templates/email/designer-signup-notification.html:43 — Swagger 링크를 설정값으로 바꾸세요. https://api.ditda.kr/swagger-ui/index.html 하드코딩은 로컬/스테이징에서 잘못된 링크를 보냅니다. 이미 있는 swagger.server-url을 템플릿 변수로 주입해 th:href로 바꾸는 편이 안전합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/resources/templates/email/designer-signup-notification.html` around
lines 42 - 46, The designer signup email template currently hardcodes the
Swagger URL, which can send the wrong link outside production. Update the link
in designer-signup-notification.html to use the existing swagger.server-url
value as a template variable and bind it with th:href instead of a fixed href,
so the button resolves correctly across environments.

@Jong0128 Jong0128 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

수고하셨습니다!
merge 해주시면 감사하겠습니다 😄

Base automatically changed from refactor/#94-notification-event to dev July 10, 2026 03:53
@fervovita
fervovita merged commit 3e8429d into dev Jul 10, 2026
2 checks passed
@fervovita
fervovita deleted the refactor/#111-timezone branch July 10, 2026 04:00
@fervovita fervovita mentioned this pull request Jul 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ENHANCEMENT] 타임존 처리 KST로 통일

2 participants