diff --git a/.env.example b/.env.example index 6d36d959..7153d487 100644 --- a/.env.example +++ b/.env.example @@ -13,6 +13,12 @@ REDIS_HOST=localhost REDIS_PORT=6379 REDIS_PASSWORD=your_redis_password +# RabbitMQ +RABBITMQ_HOST=localhost +RABBITMQ_PORT=5672 +RABBITMQ_USERNAME=your_username +RABBITMQ_PASSWORD=your_password + # S3 S3_ENDPOINT=http://localhost:9000 S3_REGION=ap-northeast-2 @@ -28,12 +34,6 @@ JWT_REFRESH_TOKEN_EXPIRATION=1209600000 JWT_COOKIE_SECURE=false JWT_REFRESH_COOKIE_PATH=/api/v1/auth -# Mail -MAIL_HOST=smtp.gmail.com -MAIL_PORT=587 -MAIL_USERNAME=your_email@gmail.com -MAIL_PASSWORD=your_app_password - # Encryption ENCRYPT_SECRET_KEY=your_encrypt_secret_key ENCRYPT_HASH_KEY=your_encrypt_hash_key diff --git a/build.gradle b/build.gradle index 836600a8..2106c5b0 100644 --- a/build.gradle +++ b/build.gradle @@ -42,17 +42,14 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-redis' implementation 'org.redisson:redisson-spring-boot-starter:4.6.1' + // rabbitMQ + implementation 'org.springframework.boot:spring-boot-starter-amqp' + // jwt implementation 'io.jsonwebtoken:jjwt-api:0.13.0' runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.13.0' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.13.0' - // email - implementation 'org.springframework.boot:spring-boot-starter-mail' - - // thymeleaf - implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' - // swagger implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:3.0.3' diff --git a/docker-compose.prod.yaml b/docker-compose.prod.yaml index d1c3458b..ffa6d678 100644 --- a/docker-compose.prod.yaml +++ b/docker-compose.prod.yaml @@ -9,6 +9,8 @@ services: depends_on: redis: condition: service_healthy + rabbitmq: + condition: service_healthy networks: - ditda-net healthcheck: @@ -28,6 +30,8 @@ services: depends_on: redis: condition: service_healthy + rabbitmq: + condition: service_healthy networks: - ditda-net healthcheck: @@ -57,6 +61,25 @@ services: timeout: 3s retries: 5 + rabbitmq: + image: rabbitmq:4.3.2-management-alpine + container_name: ditda-rabbitmq + restart: unless-stopped + environment: + RABBITMQ_DEFAULT_USER: ${RABBITMQ_USERNAME} + RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD} + volumes: + - rabbitmq-data:/var/lib/rabbitmq + networks: + - ditda-net + healthcheck: + test: [ "CMD", "rabbitmq-diagnostics", "-q", "ping" ] + interval: 10s + timeout: 5s + retries: 10 + start_period: 30s + + nginx: image: nginx:1.27-alpine container_name: ditda-nginx @@ -82,7 +105,9 @@ services: networks: ditda-net: + name: ditda-net driver: bridge volumes: - redis-data: \ No newline at end of file + redis-data: + rabbitmq-data: \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index 7b34757a..b1f49271 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -41,6 +41,24 @@ services: volumes: - redis-data:/data + rabbitmq: + image: rabbitmq:4.3.2-management-alpine + container_name: ditda-rabbitmq + ports: + - "127.0.0.1:5672:5672" # AMQP + - "127.0.0.1:15672:15672" # Admin UI + environment: + RABBITMQ_DEFAULT_USER: ${RABBITMQ_USERNAME} + RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD} + healthcheck: + test: [ "CMD", "rabbitmq-diagnostics", "-q", "ping" ] + interval: 10s + timeout: 5s + retries: 10 + start_period: 30s + volumes: + - rabbitmq-data:/var/lib/rabbitmq + minio: image: minio/minio@sha256:a1ea29fa28355559ef137d71fc570e508a214ec84ff8083e39bc5428980b015e #RELEASE.2025-04-22T22-12-26Z container_name: ditda-minio @@ -67,4 +85,5 @@ services: volumes: mysql-data: redis-data: - minio-data: \ No newline at end of file + minio-data: + rabbitmq-data: \ No newline at end of file diff --git a/scripts/deploy.sh b/scripts/deploy.sh index c06bb0bb..92c2180c 100644 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -70,6 +70,11 @@ REQUIRED_VARS=( "REDIS_HOST" "REDIS_PORT" "REDIS_PASSWORD" + # RabbitMQ + "RABBITMQ_HOST" + "RABBITMQ_PORT" + "RABBITMQ_USERNAME" + "RABBITMQ_PASSWORD" # JWT "JWT_SECRET_KEY" "JWT_ACCESS_TOKEN_EXPIRATION" @@ -77,11 +82,6 @@ REQUIRED_VARS=( "JWT_REFRESH_TOKEN_HASH_SECRET" "JWT_COOKIE_SECURE" "JWT_REFRESH_COOKIE_PATH" - # Mail - "MAIL_HOST" - "MAIL_PORT" - "MAIL_USERNAME" - "MAIL_PASSWORD" # S3 "S3_PUBLIC_BUCKET" "S3_PRIVATE_BUCKET" diff --git a/src/main/java/ditda/backend/domain/auth/exception/AuthErrorCode.java b/src/main/java/ditda/backend/domain/auth/exception/AuthErrorCode.java index 4b7bfe37..709ec94a 100644 --- a/src/main/java/ditda/backend/domain/auth/exception/AuthErrorCode.java +++ b/src/main/java/ditda/backend/domain/auth/exception/AuthErrorCode.java @@ -13,7 +13,8 @@ public enum AuthErrorCode implements BaseErrorCode { EMAIL_VERIFICATION_COOLDOWN(HttpStatus.TOO_MANY_REQUESTS, "AUTH_429_01", "잠시 후 다시 시도해주세요."), EMAIL_CODE_EXPIRED(HttpStatus.BAD_REQUEST, "AUTH_400_01", "인증번호가 만료되었거나 발급되지 않았습니다."), EMAIL_CODE_INVALID(HttpStatus.BAD_REQUEST, "AUTH_400_02", "인증번호가 일치하지 않습니다."), - EMAIL_NOT_VERIFIED(HttpStatus.BAD_REQUEST, "AUTH_400_03", "이메일 인증이 완료되지 않았습니다."); + EMAIL_NOT_VERIFIED(HttpStatus.BAD_REQUEST, "AUTH_400_03", "이메일 인증이 완료되지 않았습니다."), + EMAIL_VERIFICATION_SEND_FAILED(HttpStatus.SERVICE_UNAVAILABLE, "AUTH_503_01", "인증 메일 발송에 실패했습니다. 잠시 후 다시 시도해주세요."); private final HttpStatus httpStatus; private final String code; diff --git a/src/main/java/ditda/backend/domain/auth/notification/EmailVerificationMailer.java b/src/main/java/ditda/backend/domain/auth/notification/EmailVerificationMailer.java index 78990206..38376ab1 100644 --- a/src/main/java/ditda/backend/domain/auth/notification/EmailVerificationMailer.java +++ b/src/main/java/ditda/backend/domain/auth/notification/EmailVerificationMailer.java @@ -2,19 +2,31 @@ import java.util.Map; +import org.springframework.amqp.AmqpException; import org.springframework.stereotype.Component; -import ditda.backend.global.notification.EmailSender; +import ditda.backend.domain.auth.exception.AuthErrorCode; +import ditda.backend.global.apipayload.exception.GeneralException; +import ditda.backend.global.notification.MailMessage; +import ditda.backend.global.notification.MailPublisher; import ditda.backend.global.notification.NotificationType; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +@Slf4j @Component @RequiredArgsConstructor public class EmailVerificationMailer { - private final EmailSender emailSender; + private final MailPublisher mailPublisher; public void sendVerificationCode(String to, String code) { - emailSender.sendAsync(to, NotificationType.EMAIL_VERIFICATION, Map.of("code", code)); + NotificationType type = NotificationType.EMAIL_VERIFICATION; + try { + mailPublisher.publish(new MailMessage(type.name(), to, Map.of("code", code))); + } catch (AmqpException e) { + log.error("인증 메일 발행 실패.", e); + throw new GeneralException(AuthErrorCode.EMAIL_VERIFICATION_SEND_FAILED); + } } } diff --git a/src/main/java/ditda/backend/domain/commission/core/notification/ApplicationDeadlineClosedNotifier.java b/src/main/java/ditda/backend/domain/commission/core/notification/ApplicationDeadlineClosedNotifier.java index 1a66b41f..9e03102a 100644 --- a/src/main/java/ditda/backend/domain/commission/core/notification/ApplicationDeadlineClosedNotifier.java +++ b/src/main/java/ditda/backend/domain/commission/core/notification/ApplicationDeadlineClosedNotifier.java @@ -59,7 +59,7 @@ private void registerAdminRefundRequest(ApplicationDeadlineClosedEvent event, Lo "instructorName", event.instructorName(), "instructorEmail", event.instructorEmail(), "refundAmount", event.refundAmount(), - "isCancelled", event.cancelled() + "reason", event.cancelled() ? "APPLICATION_CANCELLED" : "APPLICATION_SHORTFALL" ), mailScheduledAt )); diff --git a/src/main/java/ditda/backend/domain/commission/core/notification/FirstDraftDeadlineClosedNotifier.java b/src/main/java/ditda/backend/domain/commission/core/notification/FirstDraftDeadlineClosedNotifier.java index 8b2223f5..948d9a4d 100644 --- a/src/main/java/ditda/backend/domain/commission/core/notification/FirstDraftDeadlineClosedNotifier.java +++ b/src/main/java/ditda/backend/domain/commission/core/notification/FirstDraftDeadlineClosedNotifier.java @@ -60,7 +60,7 @@ private void registerAdminRefundRequest( "instructorName", event.instructorName(), "instructorEmail", event.instructorEmail(), "refundAmount", event.refundAmount(), - "isCancelled", isCancelled + "reason", isCancelled ? "FIRST_DRAFT_ZERO" : "FIRST_DRAFT_SHORTFALL" ), mailScheduledAt )); diff --git a/src/main/java/ditda/backend/global/config/RabbitConfig.java b/src/main/java/ditda/backend/global/config/RabbitConfig.java new file mode 100644 index 00000000..0a6875df --- /dev/null +++ b/src/main/java/ditda/backend/global/config/RabbitConfig.java @@ -0,0 +1,35 @@ +package ditda.backend.global.config; + +import org.springframework.amqp.support.converter.JacksonJsonMessageConverter; +import org.springframework.amqp.support.converter.MessageConverter; +import org.springframework.boot.amqp.autoconfigure.RabbitTemplateCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Configuration +public class RabbitConfig { + + @Bean + public RabbitTemplateCustomizer rabbitTemplateCustomizer() { + return template -> { + template.setConfirmCallback((correlationData, ack, cause) -> { + if (!ack) { + log.error("RabbitMQ publish nack. correlationData={}, cause={}", correlationData, cause); + } + }); + + template.setReturnsCallback(returned -> { + log.error("RabbitMQ unroutable message. replyText={}, exchange={}, routingKey={}", + returned.getReplyText(), returned.getExchange(), returned.getRoutingKey()); + }); + }; + } + + @Bean + public MessageConverter messageConverter() { + return new JacksonJsonMessageConverter(); + } +} diff --git a/src/main/java/ditda/backend/global/notification/EmailSender.java b/src/main/java/ditda/backend/global/notification/EmailSender.java deleted file mode 100644 index de2196a4..00000000 --- a/src/main/java/ditda/backend/global/notification/EmailSender.java +++ /dev/null @@ -1,62 +0,0 @@ -package ditda.backend.global.notification; - -import java.util.Map; - -import org.springframework.core.io.ClassPathResource; -import org.springframework.mail.javamail.JavaMailSender; -import org.springframework.mail.javamail.MimeMessageHelper; -import org.springframework.scheduling.annotation.Async; -import org.springframework.stereotype.Component; -import org.thymeleaf.context.Context; -import org.thymeleaf.spring6.SpringTemplateEngine; - -import jakarta.mail.MessagingException; -import jakarta.mail.internet.MimeMessage; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; - -@Component -@RequiredArgsConstructor -@Slf4j -public class EmailSender { - - private static final String LOGO_CID = "logoImage"; - private static final String LOGO_PATH = "email-images/logo.png"; - - private final JavaMailSender mailSender; - private final SpringTemplateEngine templateEngine; - - // outbox 스케줄러를 통한 발송 - public void send(String to, String subject, String templateName, Map variables) - throws MessagingException { - - MimeMessage mimeMessage = mailSender.createMimeMessage(); - MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8"); - - helper.setTo(to); - helper.setSubject(subject); - helper.setText(renderTemplate(templateName, variables), true); - - helper.addInline(LOGO_CID, new ClassPathResource(LOGO_PATH)); - - mailSender.send(mimeMessage); - - log.info("Email sent. to={}, template={}", to, templateName); - } - - // 즉시 발송 - @Async - public void sendAsync(String to, NotificationType type, Map variables) { - try { - send(to, type.getSubject(), type.getTemplate(), variables); - } catch (Exception e) { - log.error("Email send failed. to={}, type={}", to, type, e); - } - } - - private String renderTemplate(String templateName, Map variables) { - Context context = new Context(); - variables.forEach(context::setVariable); - return templateEngine.process(templateName, context); - } -} diff --git a/src/main/java/ditda/backend/global/notification/MailMessage.java b/src/main/java/ditda/backend/global/notification/MailMessage.java new file mode 100644 index 00000000..99e56d35 --- /dev/null +++ b/src/main/java/ditda/backend/global/notification/MailMessage.java @@ -0,0 +1,10 @@ +package ditda.backend.global.notification; + +import java.util.Map; + +public record MailMessage( + String type, + String to, + Map variables +) { +} diff --git a/src/main/java/ditda/backend/global/notification/MailPublisher.java b/src/main/java/ditda/backend/global/notification/MailPublisher.java new file mode 100644 index 00000000..706b96b6 --- /dev/null +++ b/src/main/java/ditda/backend/global/notification/MailPublisher.java @@ -0,0 +1,27 @@ +package ditda.backend.global.notification; + +import org.springframework.amqp.rabbit.connection.CorrelationData; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.stereotype.Component; + +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +public class MailPublisher { + + private final RabbitTemplate rabbitTemplate; + + public void publish(MailMessage message) { + rabbitTemplate.convertAndSend(MailRabbitConfig.MAIL_EXCHANGE, MailRabbitConfig.MAIL_ROUTING_KEY, message); + } + + public void publish(MailMessage message, CorrelationData correlationData) { + rabbitTemplate.convertAndSend( + MailRabbitConfig.MAIL_EXCHANGE, + MailRabbitConfig.MAIL_ROUTING_KEY, + message, + correlationData + ); + } +} diff --git a/src/main/java/ditda/backend/global/notification/MailRabbitConfig.java b/src/main/java/ditda/backend/global/notification/MailRabbitConfig.java new file mode 100644 index 00000000..faa6ab46 --- /dev/null +++ b/src/main/java/ditda/backend/global/notification/MailRabbitConfig.java @@ -0,0 +1,17 @@ +package ditda.backend.global.notification; + +import org.springframework.amqp.core.DirectExchange; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class MailRabbitConfig { + + public static final String MAIL_EXCHANGE = "mail.exchange"; + public static final String MAIL_ROUTING_KEY = "mail.send"; + + @Bean + DirectExchange mailExchange() { + return new DirectExchange(MAIL_EXCHANGE); + } +} diff --git a/src/main/java/ditda/backend/global/notification/NotificationOutbox.java b/src/main/java/ditda/backend/global/notification/NotificationOutbox.java index ab38532a..e9e9380c 100644 --- a/src/main/java/ditda/backend/global/notification/NotificationOutbox.java +++ b/src/main/java/ditda/backend/global/notification/NotificationOutbox.java @@ -36,11 +36,9 @@ public class NotificationOutbox extends BaseEntity { @Column(name = "recipient_email", nullable = false, length = 100) private String recipientEmail; - @Column(name = "subject", nullable = false, length = 150) - private String subject; - - @Column(name = "template_name", nullable = false, length = 100) - private String templateName; + @Enumerated(EnumType.STRING) + @Column(name = "notification_type", nullable = false, length = 50) + private NotificationType type; @Convert(converter = MapToJsonConverter.class) @Column(name = "template_variables", nullable = false, columnDefinition = "TEXT") @@ -70,8 +68,7 @@ public static NotificationOutbox create( ) { return NotificationOutbox.builder() .recipientEmail(recipientEmail) - .subject(type.getSubject()) - .templateName(type.getTemplate()) + .type(type) .templateVariables(templateVariables) .status(OutboxStatus.PENDING) .scheduledAt(scheduledAt) diff --git a/src/main/java/ditda/backend/global/notification/NotificationOutboxScheduler.java b/src/main/java/ditda/backend/global/notification/NotificationOutboxScheduler.java index 39455d85..4dad1de4 100644 --- a/src/main/java/ditda/backend/global/notification/NotificationOutboxScheduler.java +++ b/src/main/java/ditda/backend/global/notification/NotificationOutboxScheduler.java @@ -2,7 +2,9 @@ import java.time.LocalDateTime; import java.util.List; +import java.util.concurrent.TimeUnit; +import org.springframework.amqp.rabbit.connection.CorrelationData; import org.springframework.data.domain.Limit; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; @@ -18,7 +20,7 @@ public class NotificationOutboxScheduler { private static final int BATCH_SIZE = 100; private final NotificationOutboxRepository outboxRepository; - private final EmailSender emailSender; + private final MailPublisher mailPublisher; @Scheduled(cron = "0 */10 * * * *", zone = "Asia/Seoul") public void dispatchPendingNotifications() { @@ -34,26 +36,38 @@ public void dispatchPendingNotifications() { return; } - log.info("아웃박스 알림 발송 시작. 대상 수={}", pendingAlerts.size()); + log.info("아웃박스 알림 발행 시작. 대상 수={}", pendingAlerts.size()); for (NotificationOutbox outbox : pendingAlerts) { try { - emailSender.send( + MailMessage message = new MailMessage( + outbox.getType().name(), outbox.getRecipientEmail(), - outbox.getSubject(), - outbox.getTemplateName(), outbox.getTemplateVariables() ); - outbox.markSent(); + CorrelationData correlationData = new CorrelationData(outbox.getId().toString()); + mailPublisher.publish(message, correlationData); + CorrelationData.Confirm confirm = correlationData.getFuture().get(5, TimeUnit.SECONDS); + if (confirm.ack() && correlationData.getReturned() == null) { + outbox.markSent(); + } else { + String errorMessage = !confirm.ack() ? "Broker Not Confirmed" : "Message Returned (Unroutable)"; + outbox.recordRetry(errorMessage); + } + + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + log.warn("아웃박스 알림 발행 인터럽트. outboxId={}", outbox.getId(), e); + break; } catch (Exception e) { - log.error("아웃박스 메일 발송 실패. outboxId={}", outbox.getId(), e); + log.error("아웃박스 알림 발행 실패. outboxId={}", outbox.getId(), e); outbox.recordRetry(e.getMessage()); - - // TODO: outbox.getStatus() == FAILED시 디스코드 웹훅 } + outboxRepository.save(outbox); - } + // TODO: outbox.getStatus() == FAILED시 디스코드 웹훅 + } } } diff --git a/src/main/java/ditda/backend/global/notification/NotificationType.java b/src/main/java/ditda/backend/global/notification/NotificationType.java index 984d6ad9..f372da99 100644 --- a/src/main/java/ditda/backend/global/notification/NotificationType.java +++ b/src/main/java/ditda/backend/global/notification/NotificationType.java @@ -1,80 +1,48 @@ package ditda.backend.global.notification; -import lombok.Getter; -import lombok.RequiredArgsConstructor; - -@Getter -@RequiredArgsConstructor public enum NotificationType { // 지원 마감 (ApplicationDeadlineClosed) - APPLICATION_REFUND_REQUEST_ADMIN( - "[DITDA] 외주 마감에 따른 환불 처리 요망", "email/admin-refund-request"), - APPLICATION_CANCELLED_INSTRUCTOR( - "[DITDA] 신청하신 외주가 지원자 부족으로 취소되었습니다.", "email/commission-cancelled"), - APPLICATION_SHORTFALL_INSTRUCTOR( - "[DITDA] 신청하신 외주의 모집 인원이 미달되었습니다.", "email/commission-shortfall-instructor"), - APPLICATION_MATCHED_INSTRUCTOR( - "[DITDA] 신청하신 외주의 디자이너 매칭이 완료되었습니다.", "email/commission-matched-instructor"), - APPLICATION_MATCHED_DESIGNER( - "[DITDA] 지원하신 외주의 1차 시안 대상자로 선정되었습니다.", "email/commission-matched-designer"), + APPLICATION_REFUND_REQUEST_ADMIN, + APPLICATION_CANCELLED_INSTRUCTOR, + APPLICATION_SHORTFALL_INSTRUCTOR, + APPLICATION_MATCHED_INSTRUCTOR, + APPLICATION_MATCHED_DESIGNER, // 1차 시안 마감 (FirstDraftDeadlineClosed) - FIRST_DRAFT_REFUND_REQUEST_ADMIN( - "[DITDA] 1차 시안 미제출에 따른 환불 처리 요망", "email/admin-refund-request"), - FIRST_DRAFT_ZERO_INSTRUCTOR( - "[DITDA] 1차 시안 제출이 없어 외주가 취소되었습니다.", "email/first-draft-zero-instructor"), - FIRST_DRAFT_SHORTFALL_INSTRUCTOR( - "[DITDA] 일부 디자이너의 1차 시안이 미제출되었습니다.", "email/first-draft-shortfall-instructor"), - FIRST_DRAFT_MISSED_DESIGNER( - "[DITDA] 1차 시안 기한 초과로 외주 진행이 종료되었습니다.", "email/first-draft-missed-designer"), + FIRST_DRAFT_REFUND_REQUEST_ADMIN, + FIRST_DRAFT_ZERO_INSTRUCTOR, + FIRST_DRAFT_SHORTFALL_INSTRUCTOR, + FIRST_DRAFT_MISSED_DESIGNER, // 최종 마감 (FinalDeadlineClosed) - FINAL_CANCELLED_INSTRUCTOR( - "[DITDA] 시안 선택 기한 초과로 외주가 취소되었습니다.", "email/final-cancelled-instructor"), - FINAL_CANCELLED_DESIGNER( - "[DITDA] 강사 미선택으로 외주가 취소되었습니다.", "email/final-cancelled-designer"), + FINAL_CANCELLED_INSTRUCTOR, + FINAL_CANCELLED_DESIGNER, // 전원 1차 시안 제출 (AllFirstDraftsSubmitted) - ALL_FIRST_DRAFTS_SUBMITTED_INSTRUCTOR( - "[DITDA] 모든 1차 시안이 제출되었습니다. 시안을 선택해 주세요.", "email/first-draft-all-submitted-instructor"), + ALL_FIRST_DRAFTS_SUBMITTED_INSTRUCTOR, // 시안 선택 (DraftSelected) - DRAFT_SELECTED_DESIGNER( - "[DITDA] 제출하신 1차 시안이 최종 선택되었습니다.", "email/first-draft-selected-designer"), - DRAFT_REJECTED_DESIGNER( - "[DITDA] 1차 시안 선정 결과를 안내해 드립니다.", "email/first-draft-rejected-designer"), + DRAFT_SELECTED_DESIGNER, + DRAFT_REJECTED_DESIGNER, // 외주 최종 확정 (CommissionCompleted) - COMMISSION_FINALIZED_INSTRUCTOR( - "[DITDA] 신청하신 외주가 최종 확정되었습니다.", "email/commission-finalized-instructor"), - COMMISSION_FINALIZED_DESIGNER( - "[DITDA] 작업하신 외주가 최종 확정되었습니다.", "email/commission-finalized-designer"), + COMMISSION_FINALIZED_INSTRUCTOR, + COMMISSION_FINALIZED_DESIGNER, // 수정 요청/제출 (RevisionRequested / RevisionSubmitted) - REVISION_REQUESTED_DESIGNER( - "[DITDA] 시안 수정 요청이 도착했습니다. 확인해주세요.", "email/revision-requested-designer"), - REVISION_SUBMITTED_INSTRUCTOR( - "[DITDA] 수정본이 제출되었습니다. 확인해주세요.", "email/revision-submitted-instructor"), + REVISION_REQUESTED_DESIGNER, + REVISION_SUBMITTED_INSTRUCTOR, // 정산 요청 (PayoutRequested) - PAYOUT_REQUEST_COMPLETED_ADMIN( - "[DITDA] 외주 최종 확정 - 디자이너 정산 요청", "email/admin-payout-request"), - PAYOUT_REQUEST_CANCELLED_ADMIN( - "[DITDA] 외주 취소 - 제출 디자이너 정산 요청", "email/admin-payout-request"), - PAYOUT_REQUEST_REJECTED_ADMIN( - "[DITDA] 시안 선택 완료 - 미선택 디자이너 정산 요청", "email/admin-payout-request"), + PAYOUT_REQUEST_COMPLETED_ADMIN, + PAYOUT_REQUEST_CANCELLED_ADMIN, + PAYOUT_REQUEST_REJECTED_ADMIN, // auth - EMAIL_VERIFICATION( - "[DITDA] 이메일 인증 코드", "email/verification-code"), - DESIGNER_SIGNUP_REVIEW_ADMIN( - "[DITDA] 새 디자이너 가입 검토 요청", "email/designer-signup-notification"), + EMAIL_VERIFICATION, + DESIGNER_SIGNUP_REVIEW_ADMIN, // payment - DEPOSIT_CONFIRM_REQUEST_ADMIN( - "[DITDA] 외주 입금 확인 요청", "email/deposit-notification"); - - private final String subject; - private final String template; + DEPOSIT_CONFIRM_REQUEST_ADMIN } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index cae3fb2b..be34c1a2 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -31,17 +31,15 @@ spring: max-page-size: 30 one-indexed-parameters: false - mail: - host: ${MAIL_HOST} - port: ${MAIL_PORT} - username: ${MAIL_USERNAME} - password: ${MAIL_PASSWORD} - properties: - mail: - smtp: - auth: true - starttls: - enable: true + rabbitmq: + host: ${RABBITMQ_HOST} + port: ${RABBITMQ_PORT:5672} + username: ${RABBITMQ_USERNAME} + password: ${RABBITMQ_PASSWORD} + publisher-confirm-type: correlated + publisher-returns: true + template: + mandatory: true jwt: secret: ${JWT_SECRET_KEY} diff --git a/src/main/resources/db/migration/V260715212830__add_type_to_notification_outboxes.sql b/src/main/resources/db/migration/V260715212830__add_type_to_notification_outboxes.sql new file mode 100644 index 00000000..4223f75c --- /dev/null +++ b/src/main/resources/db/migration/V260715212830__add_type_to_notification_outboxes.sql @@ -0,0 +1,15 @@ +-- =========================================================================== +-- Description: notification_outboxes 스키마를 type 기반으로 전환 +-- +-- Background: +-- - 메일 발송을 워커(RabbitMQ)로 분리하면서, Outbox가 subject/template 대신 NotificationType(enum)만 저장하도록 변경 +-- +-- Note: +-- - 실행 전 PENDING 행이 없는지 확인 (기존 행은 notification_type=''로 채워짐) +-- - subject / template_name 컬럼 제거 +-- =========================================================================== + +ALTER TABLE notification_outboxes + ADD COLUMN notification_type VARCHAR(50) NOT NULL, + DROP COLUMN subject, + DROP COLUMN template_name; \ No newline at end of file diff --git a/src/main/resources/email-images/logo.png b/src/main/resources/email-images/logo.png deleted file mode 100644 index 355f7f9c..00000000 Binary files a/src/main/resources/email-images/logo.png and /dev/null differ diff --git a/src/main/resources/templates/email/admin-payout-request.html b/src/main/resources/templates/email/admin-payout-request.html deleted file mode 100644 index 7be2e74d..00000000 --- a/src/main/resources/templates/email/admin-payout-request.html +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - -
- -
- ditda -
- -
-

디자이너 정산 요청

-

- - 외주가 자동 최종 확정되어 디자이너 정산이 필요합니다. - 외주가 강사 수동 확정되어 디자이너 정산이 필요합니다. - 외주가 강사 미선택으로 취소되어 제출 디자이너에 대한 기본금 정산이 필요합니다. - 강사가 시안을 선택하여 미선택 디자이너에 대한 기본금 정산이 필요합니다. -
- 어드민 Swagger에서 디자이너 계좌 정보를 조회 후 송금해 주세요. -

-
- - -
-

- 📌 정산 안내
- 계좌 정보는 보안상 메일에 포함되지 않습니다.
- 어드민 Swagger에서 디자이너 ID로 계좌 정보를 조회하세요. -

-
- - -
-

📋 외주 정보

-
- 외주 ID - -
-
- 외주명 - -
-
- 강사 - -
-
- - -
-

- 💰 정산 대상 - -

- -
-
- 디자이너 ID - -
-
- 디자이너 - -
-
- 정산 금액 - -
-
- -
-
- 총 정산 금액 - -
-
-
- - - -

- 본 메일은 시스템에 의해 자동 발송된 관리자 전용 알림입니다. -

-
- - diff --git a/src/main/resources/templates/email/admin-refund-request.html b/src/main/resources/templates/email/admin-refund-request.html deleted file mode 100644 index 08b6d3db..00000000 --- a/src/main/resources/templates/email/admin-refund-request.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - -
-
- ditda -
-
-

외주 마감 환불 처리 요청

-

- 외주 마감 또는 취소로 인해 정산(환불) 사유가 발생했습니다.
- 아래 내역을 확인하신 후 수동 환불을 진행해주시기 바랍니다. -

-
-
-
- 외주 ID - -
-
- 외주명 - -
-
- 강사명 - -
-
- 강사 이메일 - -
-
- 마감 형태 - 지원자 0명 (외주 취소) - 정원 미달 (부분 환불 진행) -
-
- 환불 요청액 - -
-
-

- 본 메일은 시스템에 의해 자동 발송된 관리자 전용 알림입니다. -

-
- - \ No newline at end of file diff --git a/src/main/resources/templates/email/commission-cancelled.html b/src/main/resources/templates/email/commission-cancelled.html deleted file mode 100644 index f40eac37..00000000 --- a/src/main/resources/templates/email/commission-cancelled.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - -
-
- ditda -
-
-

외주 매칭 취소 안내

-

-

- 신청하신 외주에 기간 내에 지원한 디자이너가 없어
- 아쉽게도 해당 외주가 자동 취소되었습니다.

- [환불 안내]
- 본 메일의 답장으로 환불받으실 은행과 계좌번호, 예금주명을 보내주시면,
- 확인 후 영업일 기준 2~3일 이내에 전액 환불해 드릴 예정입니다. -

-
-
-
- 외주명 - -
-
- 진행 상태 - 취소 (환불 예정) -
-
-

- ※ 본 메일은 환불 계좌 회신용으로 답장 수신이 가능합니다.
환불 계좌 외의 일반 문의사항이 있으시면 고객센터로 연락 바랍니다. -

-
- - \ No newline at end of file diff --git a/src/main/resources/templates/email/commission-finalized-designer.html b/src/main/resources/templates/email/commission-finalized-designer.html deleted file mode 100644 index ee268398..00000000 --- a/src/main/resources/templates/email/commission-finalized-designer.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - -
- -
- ditda -
- -
-

외주 최종 확정

-

-

- - 작업하신 외주의 최종 마감일이 지나
- 가장 최근 제출하신 시안이 자동으로 최종 확정되었습니다. -
- - 작업하신 외주가 최종 확정되었습니다.
- 강사님께서 시안을 최종 결과물로 확정하셨습니다. -
-

- 소중한 시간을 내어 시안을 제출해 주신 점 감사드립니다.
- 인센티브는 영업일 기준 2~3일 이내에 지급될 예정입니다. -

-
- -
-
- 외주명 - -
-
- 진행 상태 - 최종 확정 완료 -
-
- -

- 본 메일은 수신전용 메일이므로 회신되지 않습니다. -

-
- - \ No newline at end of file diff --git a/src/main/resources/templates/email/commission-finalized-instructor.html b/src/main/resources/templates/email/commission-finalized-instructor.html deleted file mode 100644 index 36576e91..00000000 --- a/src/main/resources/templates/email/commission-finalized-instructor.html +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - -
- -
- ditda -
- -
-

외주 최종 확정

-

-

- - 신청하신 외주의 최종 마감일이 지나
- 가장 최근 제출된 시안이 자동으로 최종 확정되었습니다. -
- - 신청하신 외주가 최종 확정되었습니다.
- 선택하신 시안이 최종 결과물로 확정됩니다. -
-

- 확정된 시안은 검토를 거쳐
- 영업일 기준 2~3일 내에 최종 확정본을 메일로 발송해 드립니다. -

- ditda를 - 이용해 주셔서 진심으로 감사드립니다. -

- - -
- -
-
- 외주명 - -
-
- 진행 상태 - 최종 확정 완료 -
-
- - - -

- 본 메일은 수신전용 메일이므로 회신되지 않습니다. -

-
- - \ No newline at end of file diff --git a/src/main/resources/templates/email/commission-matched-designer.html b/src/main/resources/templates/email/commission-matched-designer.html deleted file mode 100644 index 7113620c..00000000 --- a/src/main/resources/templates/email/commission-matched-designer.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - -
- -
- ditda -
- -
-

1차 시안 대상자 선정 알림

-

-

- 지원하신 외주 프로젝트의 1차 시안 대상자로 선정되셨습니다.
- 기한 내에 고품질의 1차 시안을 제출해 주시기 바랍니다. -

-
- -
-
- 외주명 - -
-
- 1차 시안 제출 마감일 - -
-
- - - -

- 마감 기한을 넘길 경우 매칭 불이익을 받을 수 있으니 기한 엄수 부탁드립니다. -

-
- - \ No newline at end of file diff --git a/src/main/resources/templates/email/commission-matched-instructor.html b/src/main/resources/templates/email/commission-matched-instructor.html deleted file mode 100644 index 1540699c..00000000 --- a/src/main/resources/templates/email/commission-matched-instructor.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - -
- -
- ditda -
- -
-

디자이너 매칭 완료!

-

-

- 신청하신 외주의 디자이너 모집 기간이 마감되어 매칭이 성공적으로 완료되었습니다.
- 디자이너들의 1차 시안 제작이 완료되는 대로 알림을 보내드리겠습니다. -

-
- -
-
- 외주명 - -
-
- 모집 디자이너 수 - -
-
- 매칭 디자이너 수 - -
-
- - - -

- 본 메일은 수신전용 메일이므로 회신되지 않습니다. -

-
- - \ No newline at end of file diff --git a/src/main/resources/templates/email/commission-shortfall-instructor.html b/src/main/resources/templates/email/commission-shortfall-instructor.html deleted file mode 100644 index 683f94e7..00000000 --- a/src/main/resources/templates/email/commission-shortfall-instructor.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - -
- -
- ditda -
- -
-

모집 인원 미달 안내

-

-

- 신청하신 외주의 모집 인원이 모두 채워지지 않아
- 매칭된 디자이너만으로 외주가 진행됩니다.

- [부분 환불 안내]
- 본 메일의 답장으로 환불받으실 은행과 계좌번호, 예금주명을 보내주시면,
- 확인 후 영업일 기준 2~3일 이내에 미달 인원분에 해당하는 금액을 환불해 드릴 예정입니다. -

-
- -
-
- 외주명 - -
-
- 모집 정원 - -
-
- 매칭 인원 - -
-
- 미달 인원 - -
-
- 환불 예정 금액 - -
-
- - - -

- ※ 본 메일은 환불 계좌 회신용으로 답장 수신이 가능합니다.
- 환불 계좌 외의 일반 문의사항은 고객센터로 연락 바랍니다. -

-
- - \ No newline at end of file diff --git a/src/main/resources/templates/email/deposit-notification.html b/src/main/resources/templates/email/deposit-notification.html deleted file mode 100644 index f3884770..00000000 --- a/src/main/resources/templates/email/deposit-notification.html +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - -
- -
- ditda -
- -
-

외주 입금 확인 요청

-

강사가 입금 완료를 통보했습니다.
입금 내역 확인 후 진행 처리 부탁드립니다.

-
- -
-
- 외주 ID - -
-
- 외주명 - -
-
- 강사 - -
-
- 입금자명 - -
-
- 금액 - -
-
- 통보 시각 - -
-
- -

- 본 메일은 자동 발송된 알림입니다. -

-
- - \ No newline at end of file diff --git a/src/main/resources/templates/email/designer-signup-notification.html b/src/main/resources/templates/email/designer-signup-notification.html deleted file mode 100644 index 0b0e88f7..00000000 --- a/src/main/resources/templates/email/designer-signup-notification.html +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - -
- -
- ditda -
- -
-

새 디자이너 가입 검토 요청

-

새로운 디자이너가 회원가입을 완료했습니다.
포트폴리오 검토 후 승인 처리 부탁드립니다.

-
- - -
-

- 📌 포트폴리오 확인 안내
- 포트폴리오는 메일에 포함되지 않습니다.
- 어드민 Swagger에서 디자이너 ID로 포트폴리오를 조회하세요. -

-
- -
-
- Designer ID - -
-
- 이름 - -
-
- 이메일 - -
-
- - - -

- 본 메일은 자동 발송된 알림입니다. -

-
- - \ No newline at end of file diff --git a/src/main/resources/templates/email/final-cancelled-designer.html b/src/main/resources/templates/email/final-cancelled-designer.html deleted file mode 100644 index a14aea7d..00000000 --- a/src/main/resources/templates/email/final-cancelled-designer.html +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - -
-
- ditda -
-
-

외주 취소 안내

-

-

- 제출하신 1차 시안에 대해 강사님의 최종 선택이 기한 내에 이루어지지 않아
- 해당 외주가 자동 취소되었습니다.

- 소중한 시간을 내어 시안을 제출해 주신 점 감사드립니다.
- 기본금은 영업일 기준 2~3일 이내에 지급될 예정입니다. -

-
-
-
- 외주명 - -
-
- 진행 상태 - 취소 -
-
-

- 본 메일은 수신전용 메일이므로 회신되지 않습니다. -

-
- - \ No newline at end of file diff --git a/src/main/resources/templates/email/final-cancelled-instructor.html b/src/main/resources/templates/email/final-cancelled-instructor.html deleted file mode 100644 index 870c4af9..00000000 --- a/src/main/resources/templates/email/final-cancelled-instructor.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - -
-
- ditda -
-
-

외주 자동 취소 안내

-

-

- 신청하신 외주의 최종 마감일까지 시안 선택이 이루어지지 않아
- 해당 외주가 자동 취소되었습니다.

- 기한 내 시안을 선택하지 않으신 점에 대한 안내로,
- 본 건은 환불 대상이 아닙니다. -

-
-
-
- 외주명 - -
-
- 진행 상태 - 취소 (환불 없음) -
-
-

- 본 메일은 수신전용 메일이므로 회신되지 않습니다.
- 문의사항은 고객센터로 연락 바랍니다. -

-
- - \ No newline at end of file diff --git a/src/main/resources/templates/email/first-draft-all-submitted-instructor.html b/src/main/resources/templates/email/first-draft-all-submitted-instructor.html deleted file mode 100644 index 46da8a0c..00000000 --- a/src/main/resources/templates/email/first-draft-all-submitted-instructor.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - -
- -
- ditda -
- -
-

1차 시안 제출 완료 안내

-

-

- 신청하신 외주의 모든 디자이너가 1차 시안 제출을 완료했습니다.
- 제출된 시안들을 확인하시고 최종 디자이너를 선택해 주세요. -

-
- -
-
- 외주명 - -
-
- 제출 시안 - -
-
- - - -

- ※ 본 메일은 발신 전용입니다. 문의사항은 고객센터로 연락 바랍니다. -

-
- - \ No newline at end of file diff --git a/src/main/resources/templates/email/first-draft-missed-designer.html b/src/main/resources/templates/email/first-draft-missed-designer.html deleted file mode 100644 index 375aff21..00000000 --- a/src/main/resources/templates/email/first-draft-missed-designer.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - -
-
- ditda -
-
-

1차 시안 기한 초과 안내

-

-

- 지원하신 외주의 1차 시안 마감일까지 시안을 제출하지 않으셔서
- 본 외주에서 자동 탈락 처리되었습니다.

- ditda에서 다시 만나뵐 수 있기를 기대합니다. -

-
-
-
- 외주명 - -
-
- 처리 결과 - 자동 탈락 -
-
-

- 본 메일은 수신전용 메일이므로 회신되지 않습니다. -

-
- - \ No newline at end of file diff --git a/src/main/resources/templates/email/first-draft-rejected-designer.html b/src/main/resources/templates/email/first-draft-rejected-designer.html deleted file mode 100644 index d095c27f..00000000 --- a/src/main/resources/templates/email/first-draft-rejected-designer.html +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - -
-
- ditda -
-
-

시안 선택 결과 안내

-

-

- 제출하신 1차 시안이 아쉽게도 이번 외주에서 선택되지 않았습니다.

- 소중한 시간을 내어 시안을 제출해 주신 점 감사드립니다.
- 기본금은 영업일 기준 2~3일 이내에 지급될 예정입니다. -

-
-
-
- 외주명 - -
-
- 결과 - 미선택 -
-
-

- 본 메일은 수신전용 메일이므로 회신되지 않습니다. -

-
- - \ No newline at end of file diff --git a/src/main/resources/templates/email/first-draft-selected-designer.html b/src/main/resources/templates/email/first-draft-selected-designer.html deleted file mode 100644 index 1f52e3f7..00000000 --- a/src/main/resources/templates/email/first-draft-selected-designer.html +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - -
-
- ditda -
-
-

시안 선택 안내

-

-

- 제출하신 1차 시안이 최종 선택되었습니다!
- 앞으로 강사님과 함께 수정 진행이 시작됩니다.

- 대시보드에서 수정 요청을 확인해 주세요. -

-
-
-
- 외주명 - -
-
- 진행 상태 - 최종 선택 완료 -
-
- -

- 본 메일은 수신전용 메일이므로 회신되지 않습니다. -

-
- - \ No newline at end of file diff --git a/src/main/resources/templates/email/first-draft-shortfall-instructor.html b/src/main/resources/templates/email/first-draft-shortfall-instructor.html deleted file mode 100644 index 144ae018..00000000 --- a/src/main/resources/templates/email/first-draft-shortfall-instructor.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - -
- -
- ditda -
- -
-

1차 시안 일부 미제출 안내

-

-

- 신청하신 외주의 1차 시안 마감일까지 일부 디자이너의 시안이 제출되지 않았습니다.
- 제출된 시안들 중에서 최종 선택을 진행해 주세요.

- [부분 환불 안내]
- 본 메일의 답장으로 환불받으실 은행과 계좌번호, 예금주명을 보내주시면,
- 확인 후 영업일 기준 2~3일 이내에 미달 인원분에 해당하는 금액을 환불해 드릴 예정입니다. -

-
- -
-
- 외주명 - -
-
- 제출 시안 - -
-
- 미제출 - -
-
- 환불 예정 금액 - -
-
- 최종 마감일 - -
-
- - - -

- ※ 본 메일은 환불 계좌 회신용으로 답장 수신이 가능합니다.
- 환불 계좌 외의 일반 문의사항은 고객센터로 연락 바랍니다. -

-
- - \ No newline at end of file diff --git a/src/main/resources/templates/email/first-draft-zero-instructor.html b/src/main/resources/templates/email/first-draft-zero-instructor.html deleted file mode 100644 index dca7079f..00000000 --- a/src/main/resources/templates/email/first-draft-zero-instructor.html +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - -
- -
- ditda -
- -
-

외주 자동 취소 안내

-

-

- 신청하신 외주의 1차 시안 마감일까지 제출된 시안이 없어
- 아쉽게도 해당 외주가 자동 취소되었습니다.

- [환불 안내]
- 본 메일의 답장으로 환불받으실 은행과 계좌번호, 예금주명을 보내주시면,
- 확인 후 영업일 기준 2~3일 이내에 전액 환불해 드릴 예정입니다. -

-
- -
-
- 외주명 - -
-
- 진행 상태 - 취소 (환불 예정) -
-
- 환불 금액 - -
-
- -

- ※ 본 메일은 환불 계좌 회신용으로 답장 수신이 가능합니다.
- 환불 계좌 외의 일반 문의사항은 고객센터로 연락 바랍니다. -

-
- - \ No newline at end of file diff --git a/src/main/resources/templates/email/revision-requested-designer.html b/src/main/resources/templates/email/revision-requested-designer.html deleted file mode 100644 index 5bf9529b..00000000 --- a/src/main/resources/templates/email/revision-requested-designer.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - -
- -
- ditda -
- -
-

시안 수정 요청 안내

-

-

- 강사님으로부터 시안 수정 요청이 도착했습니다.
- 요청 내용을 확인하시고 가능한 빠르게 수정본을 제출해 주세요. -

-
- -
-
- 외주명 - -
-
- 수정 차수 - -
-
- - - -

- 제출이 지연되면 남은 수정 기회에 영향을 줄 수 있으니 신속히 진행해 주세요. -

- -

- 본 메일은 발신 전용입니다. -

-
- - \ No newline at end of file diff --git a/src/main/resources/templates/email/revision-submitted-instructor.html b/src/main/resources/templates/email/revision-submitted-instructor.html deleted file mode 100644 index dfc086a2..00000000 --- a/src/main/resources/templates/email/revision-submitted-instructor.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - -
- -
- ditda -
- -
-

수정본 제출 안내

-

-

- 요청하신 수정 사항에 대한 수정본이 제출되었습니다.
- 제출된 수정본을 확인해 주세요. -

-
- -
-
- 외주명 - -
-
- 수정 차수 - -
-
- - - -

- 본 메일은 발신 전용입니다. -

-
- - \ No newline at end of file diff --git a/src/main/resources/templates/email/verification-code.html b/src/main/resources/templates/email/verification-code.html deleted file mode 100644 index 120e3271..00000000 --- a/src/main/resources/templates/email/verification-code.html +++ /dev/null @@ -1,27 +0,0 @@ - - - - - Ditda 이메일 인증 - - -
- - -
- ditda -
- -
-

ditda 이메일 인증번호

-

아래 인증번호를 입력해주세요.

-
- 0000 -
-

- 인증번호는 5분간 유효합니다. -

-
-
- - \ No newline at end of file diff --git a/src/test/resources/application-test.yaml b/src/test/resources/application-test.yaml index 2b9cd51d..af2195ed 100644 --- a/src/test/resources/application-test.yaml +++ b/src/test/resources/application-test.yaml @@ -12,17 +12,11 @@ spring: port: 6370 password: - mail: - host: 127.0.0.1 - port: 3025 - username: test - password: test - properties: - mail: - smtp: - auth: true - starttls: - enable: false + rabbitmq: + host: localhost + port: 5672 + username: guest + password: guest cloud: aws: