[FEATURE] 메일 발송 로직 및 템플릿 이관 - #4
Conversation
|
Warning Review limit reached
Next review available in: 14 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (7)
📝 WalkthroughWalkthrough메일 환경 설정과 알림 유형 매핑을 추가하고, RabbitMQ 메시지를 Thymeleaf 기반 HTML 메일로 렌더링해 SMTP로 전송하는 기능을 구현했습니다. 외주 상태·관리자 알림·인증 코드용 이메일 템플릿도 추가했습니다. Changes메일 발송 기능
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant MailListener
participant NotificationType
participant EmailSender
participant SpringTemplateEngine
participant JavaMailSender
MailListener->>NotificationType: 메시지 유형 변환
MailListener->>EmailSender: 수신자·유형·변수 전달
EmailSender->>SpringTemplateEngine: 템플릿 렌더링
EmailSender->>JavaMailSender: MIME 메일 전송
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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 |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (4)
src/main/resources/templates/email/admin-payout-request.html (1)
89-92: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value환경별 Swagger URL 분리 고려 (선택 사항)
현재 Swagger URL이 운영 환경(
https://api.ditda.kr...)으로 하드코딩되어 있습니다. 개발이나 스테이징 환경에서 발송된 메일을 확인할 때 운영 환경으로 잘못 연결되어 혼동을 줄 수 있습니다.서버의 도메인을 변수로 주입받아 동적으로 URL을 구성하는 것을 고려해 보세요.
🤖 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/admin-payout-request.html` around lines 89 - 92, Update the Swagger link in the email template to use an injected server-domain or environment-specific base URL instead of the hardcoded production host, while preserving the existing Swagger path and link text.src/main/resources/templates/email/first-draft-all-submitted-instructor.html (2)
34-38: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win환경(Environment)별 라우팅을 위한 URL 변수화 권장
이메일 템플릿 내에 도메인 URL이 하드코딩되어 있습니다. 개발(Dev)이나 테스트(Staging) 환경에서 발송된 이메일의 링크를 클릭할 경우에도 운영(Prod) 환경으로 강제 연결되는 문제가 발생할 수 있습니다. 서버 환경에 맞는 Base URL을 변수(예:
th:href="@{${baseUrl} + '/instructor'}")로 주입받아 동적으로 구성하는 것을 권장합니다.
src/main/resources/templates/email/first-draft-all-submitted-instructor.html#L34-L38: 하드코딩된https://ditda.kr/instructor를 변수를 활용한 동적 URL로 변경을 고려해 주세요.src/main/resources/templates/email/first-draft-missed-designer.html#L14-L18: 하드코딩된https://www.ditda.kr를 변수를 활용한 동적 URL로 변경을 고려해 주세요.src/main/resources/templates/email/revision-submitted-instructor.html#L34-L38: 하드코딩된https://ditda.kr/instructor를 변수를 활용한 동적 URL로 변경을 고려해 주세요.🤖 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/first-draft-all-submitted-instructor.html` around lines 34 - 38, Replace the hardcoded production links in first-draft-all-submitted-instructor.html (lines 34-38), first-draft-missed-designer.html (lines 14-18), and revision-submitted-instructor.html (lines 34-38) with Thymeleaf URLs built from the injected environment-specific baseUrl variable, preserving each template’s existing destination path.
3-5: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win모바일 기기 호환성을 위한 뷰포트(Viewport) 메타 태그 누락
이메일 템플릿에 뷰포트 메타 태그가 누락되어 있어 모바일 이메일 클라이언트에서 내용이 지나치게 작게 표시되거나 화면 배율이 맞지 않을 수 있습니다. 모든 템플릿의
<head>영역에<meta name="viewport" content="width=device-width, initial-scale=1.0">를 추가하는 것을 권장합니다.
src/main/resources/templates/email/first-draft-all-submitted-instructor.html#L3-L5:<head>내에<meta name="viewport" content="width=device-width, initial-scale=1.0">태그를 추가합니다.src/main/resources/templates/email/first-draft-missed-designer.html#L3-L5: 동일하게 모바일 뷰포트 메타 태그를 추가합니다.src/main/resources/templates/email/first-draft-rejected-designer.html#L3-L5: 동일하게 모바일 뷰포트 메타 태그를 추가합니다.src/main/resources/templates/email/revision-submitted-instructor.html#L3-L5: 동일하게 모바일 뷰포트 메타 태그를 추가합니다.src/main/resources/templates/email/verification-code.html#L3-L6: 동일하게 모바일 뷰포트 메타 태그를 추가합니다.🤖 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/first-draft-all-submitted-instructor.html` around lines 3 - 5, 모든 이메일 템플릿의 <head> 영역에 모바일 뷰포트 메타 태그를 추가하세요: src/main/resources/templates/email/first-draft-all-submitted-instructor.html 3-5, src/main/resources/templates/email/first-draft-missed-designer.html 3-5, src/main/resources/templates/email/first-draft-rejected-designer.html 3-5, src/main/resources/templates/email/revision-submitted-instructor.html 3-5, src/main/resources/templates/email/verification-code.html 3-6. 각 파일의 기존 charset 메타 태그와 함께 동일한 viewport 설정을 배치하세요.src/main/resources/templates/email/first-draft-selected-designer.html (1)
31-34: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value하드코딩된 프로덕션 URL을 환경 변수 기반으로 변경하는 것을 고려해 보세요.
세 곳의 템플릿 파일에서
https://ditda.kr과 같이 운영 환경의 도메인이 하드코딩되어 있습니다. 추후 로컬, 개발(dev), 스테이징 등 다양한 환경에서 원활하게 이메일 내 링크를 테스트할 수 있도록 백엔드에서baseUrl같은 변수를 주입받아 동적으로 사용하는 방식을 권장합니다.
src/main/resources/templates/email/first-draft-selected-designer.html#L31-L34:href="https://ditda.kr/designer"경로 사용 중src/main/resources/templates/email/first-draft-shortfall-instructor.html#L50-L53:href="https://ditda.kr/instructor"경로 사용 중src/main/resources/templates/email/revision-requested-designer.html#L34-L37:href="https://ditda.kr/designer"경로 사용 중💡 수정 예시 (타임리프 변수 활용)
<!-- Java 코드에서 variables.put("baseUrl", "https://ditda.kr"); 설정 후 --> <a th:href="@{|${baseUrl}/designer|}" style="display: inline-block; padding: 12px 24px; background: `#874fff`; color: `#fff`; text-decoration: none; border-radius: 8px; font-weight: bold; font-size: 14px;"> 대시보드 바로가기 </a>🤖 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/first-draft-selected-designer.html` around lines 31 - 34, Replace the hardcoded https://ditda.kr links with an injected baseUrl and construct each destination path dynamically. Update first-draft-selected-designer.html:31-34 for /designer, first-draft-shortfall-instructor.html:50-53 for /instructor, and revision-requested-designer.html:34-37 for /designer; ensure the backend populates baseUrl for every email template context.
🤖 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/notification/mail/EmailSender.java`:
- Around line 57-61: Update renderTemplate to handle a null variables argument
before invoking variables.forEach; only populate the Context when variables is
non-null, while preserving templateEngine.process behavior for templates without
variables.
In `@src/main/resources/application.yaml`:
- Line 22: Update the spring.rabbitmq.listener.simple.retry configuration key
from max-retries to max-attempts while preserving the configured value of 2.
In `@src/main/resources/templates/email/admin-payout-request.html`:
- Around line 74-76: Update the formatInteger calls in
src/main/resources/templates/email/admin-payout-request.html at lines 74-76 and
82-84 to use minIntegerDigits 1 instead of 3, and update the call in
src/main/resources/templates/email/admin-refund-request.html at lines 42-44 to
use 1 instead of 0, preserving comma grouping and the existing 원 suffix.
In `@src/main/resources/templates/email/admin-refund-request.html`:
- Around line 36-39: Update the “마감 형태” section in admin-refund-request.html to
render the refund reason from the reason variable, matching the
notification-specific wording used by admin-payout-request.html. Remove the
hardcoded “지원자 0명” and “정원 미달” branches while preserving the existing styling
and layout.
In `@src/main/resources/templates/email/commission-shortfall-instructor.html`:
- Around line 44-45: 금액 포매팅의 최소 정수 자릿수를 1로 통일하세요.
src/main/resources/templates/email/commission-shortfall-instructor.html 44-45의
refundAmount 포매팅을 3에서 1로 변경하고,
src/main/resources/templates/email/deposit-notification.html 37-37의 amount 포매팅을
0에서 1로 변경하세요.
---
Nitpick comments:
In `@src/main/resources/templates/email/admin-payout-request.html`:
- Around line 89-92: Update the Swagger link in the email template to use an
injected server-domain or environment-specific base URL instead of the hardcoded
production host, while preserving the existing Swagger path and link text.
In
`@src/main/resources/templates/email/first-draft-all-submitted-instructor.html`:
- Around line 34-38: Replace the hardcoded production links in
first-draft-all-submitted-instructor.html (lines 34-38),
first-draft-missed-designer.html (lines 14-18), and
revision-submitted-instructor.html (lines 34-38) with Thymeleaf URLs built from
the injected environment-specific baseUrl variable, preserving each template’s
existing destination path.
- Around line 3-5: 모든 이메일 템플릿의 <head> 영역에 모바일 뷰포트 메타 태그를 추가하세요:
src/main/resources/templates/email/first-draft-all-submitted-instructor.html
3-5, src/main/resources/templates/email/first-draft-missed-designer.html 3-5,
src/main/resources/templates/email/first-draft-rejected-designer.html 3-5,
src/main/resources/templates/email/revision-submitted-instructor.html 3-5,
src/main/resources/templates/email/verification-code.html 3-6. 각 파일의 기존 charset
메타 태그와 함께 동일한 viewport 설정을 배치하세요.
In `@src/main/resources/templates/email/first-draft-selected-designer.html`:
- Around line 31-34: Replace the hardcoded https://ditda.kr links with an
injected baseUrl and construct each destination path dynamically. Update
first-draft-selected-designer.html:31-34 for /designer,
first-draft-shortfall-instructor.html:50-53 for /instructor, and
revision-requested-designer.html:34-37 for /designer; ensure the backend
populates baseUrl for every email template context.
🪄 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: 461fccae-124e-4b6b-8e90-4004ff273d1f
⛔ Files ignored due to path filters (1)
src/main/resources/email-images/logo.pngis excluded by!**/*.png
📒 Files selected for processing (29)
.env.examplescripts/deploy.shsrc/main/java/ditda/notification/mail/EmailSender.javasrc/main/java/ditda/notification/mail/MailListener.javasrc/main/java/ditda/notification/mail/MailMasker.javasrc/main/java/ditda/notification/mail/NotificationType.javasrc/main/resources/application.yamlsrc/main/resources/templates/email/admin-payout-request.htmlsrc/main/resources/templates/email/admin-refund-request.htmlsrc/main/resources/templates/email/commission-cancelled.htmlsrc/main/resources/templates/email/commission-finalized-designer.htmlsrc/main/resources/templates/email/commission-finalized-instructor.htmlsrc/main/resources/templates/email/commission-matched-designer.htmlsrc/main/resources/templates/email/commission-matched-instructor.htmlsrc/main/resources/templates/email/commission-shortfall-instructor.htmlsrc/main/resources/templates/email/deposit-notification.htmlsrc/main/resources/templates/email/designer-signup-notification.htmlsrc/main/resources/templates/email/final-cancelled-designer.htmlsrc/main/resources/templates/email/final-cancelled-instructor.htmlsrc/main/resources/templates/email/first-draft-all-submitted-instructor.htmlsrc/main/resources/templates/email/first-draft-missed-designer.htmlsrc/main/resources/templates/email/first-draft-rejected-designer.htmlsrc/main/resources/templates/email/first-draft-selected-designer.htmlsrc/main/resources/templates/email/first-draft-shortfall-instructor.htmlsrc/main/resources/templates/email/first-draft-zero-instructor.htmlsrc/main/resources/templates/email/revision-requested-designer.htmlsrc/main/resources/templates/email/revision-submitted-instructor.htmlsrc/main/resources/templates/email/verification-code.htmlsrc/test/resources/application-test.yaml
🚀 Related issue
Closes #3
#️⃣ Summary
🔧 Changes
💬 Reviewer Notes
Summary by CodeRabbit
새로운 기능
개선 사항