Skip to content

Commit b8677e7

Browse files
authored
Merge pull request #273 from prgrms-aibe-devcourse/refector/smtp
refector: 알림 리팩토링
2 parents 477ae54 + 38c1097 commit b8677e7

40 files changed

Lines changed: 1837 additions & 1033 deletions

src/main/java/store/lastdance/config/MailConfig.java

Lines changed: 16 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@
33
import org.springframework.beans.factory.annotation.Value;
44
import org.springframework.context.annotation.Bean;
55
import org.springframework.context.annotation.Configuration;
6-
import org.springframework.context.annotation.Primary;
7-
import org.springframework.mail.javamail.JavaMailSender;
86
import org.springframework.mail.javamail.JavaMailSenderImpl;
9-
import org.springframework.util.StringUtils;
107

118
import java.util.Properties;
129

@@ -33,60 +30,36 @@ public class MailConfig {
3330
@Value("${spring.mail.naver.password}")
3431
private String naverPassword;
3532

36-
@Bean("gmailSender")
37-
public JavaMailSender gmailSender() {
38-
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
39-
mailSender.setHost(gmailHost);
40-
mailSender.setPort(gmailPort);
41-
mailSender.setUsername(gmailUsername);
42-
mailSender.setPassword(gmailPassword);
43-
44-
Properties props = mailSender.getJavaMailProperties();
33+
@Bean("gmailSenderConfig")
34+
public MailSenderConfig gmailSenderConfig() {
35+
Properties props = new Properties();
4536
props.put("mail.transport.protocol", "smtp");
4637
props.put("mail.smtp.auth", "true");
4738
props.put("mail.smtp.starttls.enable", "true");
4839
props.put("mail.smtp.ssl.enable", "false");
4940
props.put("mail.debug", "false");
5041

51-
return mailSender;
42+
return buildConfig(gmailHost, gmailPort, gmailUsername, gmailPassword, props);
5243
}
5344

54-
@Bean("naverSender")
55-
public JavaMailSender naverSender() {
56-
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
57-
mailSender.setHost(naverHost);
58-
mailSender.setPort(naverPort);
59-
mailSender.setUsername(naverUsername);
60-
mailSender.setPassword(naverPassword);
61-
62-
Properties props = mailSender.getJavaMailProperties();
45+
@Bean("naverSenderConfig")
46+
public MailSenderConfig naverSenderConfig() {
47+
Properties props = new Properties();
6348
props.put("mail.transport.protocol", "smtp");
6449
props.put("mail.smtp.auth", "true");
6550
props.put("mail.smtp.ssl.enable", "true");
6651
props.put("mail.debug", "false");
6752

68-
return mailSender;
69-
}
70-
71-
@Bean("gmailFromEmail")
72-
public String gmailFromEmail() {
73-
return StringUtils.hasText(gmailUsername) ? gmailUsername : "lastdance857@gmail.com";
74-
}
75-
76-
@Bean("naverFromEmail")
77-
public String naverFromEmail() {
78-
return StringUtils.hasText(naverUsername) ? naverUsername : "lastdance857@naver.com";
53+
return buildConfig(naverHost, naverPort, naverUsername, naverPassword, props);
7954
}
8055

81-
@Bean
82-
@Primary
83-
public JavaMailSender defaultMailSender() {
84-
if (StringUtils.hasText(gmailUsername)) {
85-
return gmailSender();
86-
} else if (StringUtils.hasText(naverUsername)) {
87-
return naverSender();
88-
} else {
89-
throw new IllegalStateException("메일 설정이 없습니다.");
90-
}
56+
private MailSenderConfig buildConfig(String host, int port, String username, String password, Properties props) {
57+
JavaMailSenderImpl sender = new JavaMailSenderImpl();
58+
sender.setHost(host);
59+
sender.setPort(port);
60+
sender.setUsername(username);
61+
sender.setPassword(password);
62+
sender.setJavaMailProperties(props);
63+
return new MailSenderConfig(sender, username);
9164
}
9265
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package store.lastdance.config;
2+
3+
import org.springframework.mail.javamail.JavaMailSender;
4+
5+
public record MailSenderConfig(JavaMailSender sender, String fromEmail) {}

src/main/java/store/lastdance/config/SSEConfig.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55
import org.springframework.context.annotation.Configuration;
66
import org.springframework.context.event.ContextClosedEvent;
77
import org.springframework.context.event.EventListener;
8-
import store.lastdance.exception.CustomException;
9-
import store.lastdance.exception.ErrorCode;
10-
import store.lastdance.service.notification.SSENotificationV2Service;
8+
import store.lastdance.service.notification.sse.SSENotificationV2Service;
119

1210
@Slf4j
1311
@Configuration

src/main/java/store/lastdance/controller/notification/SSEV2Controller.java

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@
1010
import org.springframework.web.bind.annotation.*;
1111
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
1212
import store.lastdance.security.oauth.CustomOAuth2User;
13-
import store.lastdance.service.notification.NotificationV2Service;
14-
import store.lastdance.service.notification.SSENotificationV2Service;
13+
import store.lastdance.service.notification.sse.SSENotificationV2Service;
1514

16-
import java.util.Map;
1715
import java.util.UUID;
1816

1917
@Tag(name = "SSE 실시간 알림", description = "Server-Sent Events 기반 실시간 알림 API")
@@ -23,7 +21,6 @@
2321
public class SSEV2Controller {
2422

2523
private final SSENotificationV2Service sseService;
26-
private final NotificationV2Service notificationService;
2724

2825
@Operation(summary = "실시간 알림 스트림 연결", description = "SSE를 통한 실시간 알림 수신 연결을 생성합니다. 응답 헤더 X-Connection-Id로 연결 ID를 확인할 수 있습니다.")
2926
@ApiResponse(responseCode = "200", description = "스트림 연결 성공")
@@ -39,36 +36,4 @@ public ResponseEntity<SseEmitter> streamNotifications(@AuthenticationPrincipal C
3936
.header("X-Connection-Id", connectionId)
4037
.body(emitter);
4138
}
42-
43-
@Operation(summary = "알림 읽음 처리", description = "특정 알림을 읽음 상태로 처리합니다.")
44-
@ApiResponse(responseCode = "200", description = "읽음 처리 성공")
45-
@PostMapping("/read/{notificationId}")
46-
public ResponseEntity<Map<String, String>> markAsRead(
47-
@AuthenticationPrincipal CustomOAuth2User user,
48-
@PathVariable String notificationId) {
49-
50-
notificationService.markNotificationAsRead(user.getUserId(), notificationId);
51-
52-
return ResponseEntity.ok(Map.of(
53-
"message", "알림이 읽음 처리되었습니다.",
54-
"notificationId", notificationId,
55-
"userId", user.getUserId().toString()
56-
));
57-
}
58-
59-
@Operation(summary = "알림 읽음 상태 확인", description = "특정 알림의 읽음 상태를 확인합니다.")
60-
@ApiResponse(responseCode = "200", description = "읽음 상태 확인 성공")
61-
@GetMapping("/read/{notificationId}")
62-
public ResponseEntity<Map<String, Object>> checkReadStatus(
63-
@AuthenticationPrincipal CustomOAuth2User user,
64-
@PathVariable String notificationId) {
65-
66-
boolean isRead = notificationService.isNotificationRead(user.getUserId(), notificationId);
67-
68-
return ResponseEntity.ok(Map.of(
69-
"notificationId", notificationId,
70-
"userId", user.getUserId().toString(),
71-
"isRead", isRead
72-
));
73-
}
7439
}

src/main/java/store/lastdance/domain/notification/NotificationRead.java

Lines changed: 0 additions & 47 deletions
This file was deleted.

src/main/java/store/lastdance/domain/notification/NotificationSetting.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public class NotificationSetting {
1919

2020
@Column(name = "user_id", unique = true, nullable = false)
2121
private UUID userId;
22-
22+
2323
@Column(name = "email_enabled", nullable = false)
2424
private boolean emailEnabled = false;
2525

@@ -45,6 +45,12 @@ public class NotificationSetting {
4545
@Builder
4646
public NotificationSetting(@NonNull UUID userId) {
4747
this.userId = userId;
48+
this.emailEnabled = false;
49+
this.scheduleReminder = false;
50+
this.paymentReminder = false;
51+
this.checklistReminder = false;
52+
this.sseEnabled = false;
53+
this.createdAt = LocalDateTime.now();
4854
}
4955

5056
public void updateEmailEnabled(boolean emailEnabled) {
Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,22 @@
11
package store.lastdance.domain.notification;
22

33
import lombok.Getter;
4+
import lombok.RequiredArgsConstructor;
5+
46

57
@Getter
8+
@RequiredArgsConstructor
69
public enum NotificationType {
7-
SCHEDULE("일정"),
8-
PAYMENT("납부일"),
9-
CHECKLIST("할일");
1010

11-
private final String description;
11+
SCHEDULE("일정", "📅", "일정", "📌", "잊지 마시고 준비해 주세요!"),
12+
PAYMENT ("납부일", "💳", "지출 항목", "📊", "그룹 지출에 대한 정산이 요청되었습니다.\n앱에서 확인해 주세요!"),
13+
CHECKLIST("할일", "✅", "할일", "📝", "완료하는 것을 잊지 마세요!");
14+
15+
private final String description; // 한글 설명 (기존 유지)
16+
private final String icon; // 제목용 이모지
17+
private final String label; // 항목 유형명
18+
private final String bodyIcon; // 본문 항목 이모지
19+
private final String closingMessage; // 본문 마무리 문구
1220

13-
NotificationType(String description) {
14-
this.description = description;
15-
}
1621

17-
// 아이콘 반환
18-
public String getIcon() {
19-
return switch (this) {
20-
case SCHEDULE -> "📅";
21-
case PAYMENT -> "💳";
22-
case CHECKLIST -> "✅";
23-
};
24-
}
25-
}
22+
}

src/main/java/store/lastdance/domain/user/OAuthProvider.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,9 @@
33
public enum OAuthProvider {
44
KAKAO,
55
GOOGLE,
6-
NAVER
6+
NAVER;
7+
8+
public boolean isNaverMail() {
9+
return this == NAVER;
10+
}
711
}

src/main/java/store/lastdance/dto/notification/NotificationReadRequestDTO.java

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/main/java/store/lastdance/repository/redis/NotificationReadRepository.java

Lines changed: 0 additions & 14 deletions
This file was deleted.

0 commit comments

Comments
 (0)