-
Notifications
You must be signed in to change notification settings - Fork 2
MOSU-28 feat: 알림톡 기능 구현 #104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5d47a07
44eb9f3
f9a4a8a
abeeae7
f1828d8
397caea
e65f5e2
f4247b5
8a2bbd5
d76a5c8
ecbca02
97b4ad8
bc5b2dd
34ed522
f245fd3
401a17a
633d821
88c9b4d
4cd5e74
2a0a9c1
9ff2c9a
32009b9
f118a2d
d768f97
747d4bb
d5400be
7977e6c
5d80983
8601b0a
79e5ec6
c5e51ed
aa28d41
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ | |
| import life.mosu.mosuserver.domain.applicationschool.ApplicationSchoolJpaRepository; | ||
| import life.mosu.mosuserver.domain.school.SchoolJpaEntity; | ||
| import life.mosu.mosuserver.domain.school.SchoolJpaRepository; | ||
| import life.mosu.mosuserver.domain.school.SchoolQueryRepositoryImpl; | ||
| import life.mosu.mosuserver.global.exception.CustomRuntimeException; | ||
| import life.mosu.mosuserver.global.exception.ErrorCode; | ||
| import life.mosu.mosuserver.global.util.FileRequest; | ||
|
|
@@ -31,6 +32,7 @@ public class ApplicationService { | |
| private final ApplicationJpaRepository applicationJpaRepository; | ||
| private final ApplicationSchoolJpaRepository applicationSchoolJpaRepository; | ||
| private final AdmissionTicketImageJpaRepository admissionTicketImageJpaRepository; | ||
| private final SchoolQueryRepositoryImpl schoolQueryRepository; | ||
| private final SchoolJpaRepository schoolJpaRepository; | ||
|
|
||
| // 신청 | ||
|
|
@@ -42,32 +44,85 @@ public ApplicationResponse apply(Long userId, ApplicationRequest request) { | |
| ApplicationJpaEntity application = applicationJpaRepository.save(request.toEntity(userId)); | ||
| Long applicationId = application.getId(); | ||
|
|
||
| //수험표 저장 | ||
| admissionTicketImageJpaRepository.save( | ||
| createAdmissionTicketImageIfPresent(request.admissionTicket(), applicationId)); | ||
|
|
||
| for (ApplicationSchoolRequest schoolRequest : schoolRequests) { | ||
| //해당 학교가 존재하는 학교인지 | ||
| Long schoolId = schoolJpaRepository.findBySchoolNameAndAreaAndExamDate( | ||
| schoolRequest.schoolName(), | ||
| schoolRequest.validatedArea(schoolRequest.area()), | ||
| schoolRequest.examDate()) | ||
| .orElseThrow(() -> new CustomRuntimeException(ErrorCode.SCHOOL_NOT_FOUND)) | ||
| .getId(); | ||
|
|
||
| //해당 학교를 이미 신청하였는지 | ||
| if (applicationSchoolJpaRepository.existsByUserIdAndSchoolId(userId, schoolId)) { | ||
| throw new CustomRuntimeException(ErrorCode.APPLICATION_SCHOOL_ALREADY_APPLIED); | ||
| } | ||
|
|
||
| //해당 학교를 찾을 수 있는지 | ||
| SchoolJpaEntity school = schoolJpaRepository.findById(schoolId) | ||
| .orElseThrow(() -> new CustomRuntimeException(ErrorCode.SCHOOL_NOT_FOUND)); | ||
|
Comment on lines
48
to
67
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 학교 존재 확인과 기존의 신청이 있는지 검증을 하고 수험표 저장 로직을 수행해야 할 것 같은데 혹시 다른 의도가 있는 건가요?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 수정 중에 있습니다! 확인했어요 |
||
|
|
||
| //해당 학교를 신청했음을 저장하기 | ||
| ApplicationSchoolJpaEntity applicationSchool = schoolRequest.toEntity(userId, | ||
| applicationId, school); | ||
|
|
||
| //반환용 리스트에 저장하기 | ||
| savedEntities.add(applicationSchoolJpaRepository.save(applicationSchool)); | ||
| } | ||
|
|
||
| return ApplicationResponse.of(applicationId, savedEntities); | ||
| } | ||
|
|
||
| //신청 - 리팩토링 | ||
| // @Transactional | ||
| // public ApplicationResponse apply(Long userId, ApplicationRequest request) { | ||
| // Set<ApplicationSchoolRequest> schoolRequests = request.schools(); | ||
| //// List<ApplicationSchoolJpaEntity> savedEntities = new ArrayList<>(); | ||
| // | ||
| // ApplicationJpaEntity application = applicationJpaRepository.save(request.toEntity(userId)); | ||
| // Long applicationId = application.getId(); | ||
| // | ||
| // //수험표 저장 | ||
| // admissionTicketImageJpaRepository.save( | ||
| // createAdmissionTicketImageIfPresent(request.admissionTicket(), applicationId)); | ||
| // | ||
| // List<Triple<String, Area, LocalDate>> conditions = schoolRequests.stream() | ||
| // .map(school -> Triple.of( | ||
| // school.schoolName(), | ||
| // school.validatedArea(school.area()), | ||
| // school.examDate() | ||
| // )) | ||
| // .toList(); | ||
| // | ||
| // //이름, 지역, 날짜 조건에 맞는 학교가 있는지 | ||
| // List<Long> schoolIds = schoolQueryRepository.findSchoolsByConditions(conditions); | ||
| // if (schoolIds.size() != conditions.size()) { | ||
| // throw new CustomRuntimeException(ErrorCode.SCHOOL_NOT_FOUND); | ||
| // } | ||
| // | ||
| // //해당 학교를 이미 신청하였는지 | ||
| // if (applicationSchoolJpaRepository.existsByUserIdAndSchoolIds(userId, schoolIds)) { | ||
| // throw new CustomRuntimeException(ErrorCode.APPLICATION_SCHOOL_ALREADY_APPLIED); | ||
| // } | ||
| // | ||
|
|
||
| /// / //해당 학교를 찾을 수 있는지 / SchoolJpaEntity school = | ||
| /// schoolJpaRepository.findById(schoolId) / .orElseThrow(() -> new | ||
| /// CustomRuntimeException(ErrorCode.SCHOOL_NOT_FOUND)); | ||
| // | ||
| // //해당 학교를 신청했음을 저장하기 | ||
| // ApplicationSchoolJpaEntity applicationSchool = schoolRequest.toEntity(userId, | ||
| // applicationId, school); | ||
| // | ||
| // //반환용 리스트에 저장하기 | ||
| // savedEntities.add(applicationSchoolJpaRepository.save(applicationSchool)); | ||
| // | ||
| // return ApplicationResponse.of(applicationId, savedEntities); | ||
| // } | ||
jbh010204 marked this conversation as resolved.
Show resolved
Hide resolved
jbh010204 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // 전체 신청 내역 조회 | ||
| @Transactional(readOnly = true, propagation = Propagation.SUPPORTS) | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,41 @@ | ||||||||||||||||||||||
| package life.mosu.mosuserver.application.notify; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| import life.mosu.mosuserver.domain.profile.ProfileJpaEntity; | ||||||||||||||||||||||
| import life.mosu.mosuserver.domain.profile.ProfileJpaRepository; | ||||||||||||||||||||||
| import life.mosu.mosuserver.global.exception.CustomRuntimeException; | ||||||||||||||||||||||
| import life.mosu.mosuserver.global.exception.ErrorCode; | ||||||||||||||||||||||
| import life.mosu.mosuserver.infra.notify.NotifyClientAdapter; | ||||||||||||||||||||||
| import life.mosu.mosuserver.infra.notify.dto.NotifyEvent; | ||||||||||||||||||||||
| import life.mosu.mosuserver.infra.notify.dto.NotifyEventRequest; | ||||||||||||||||||||||
| import life.mosu.mosuserver.infra.notify.strategy.NotifyStrategy; | ||||||||||||||||||||||
| import lombok.RequiredArgsConstructor; | ||||||||||||||||||||||
| import lombok.extern.slf4j.Slf4j; | ||||||||||||||||||||||
| import org.springframework.context.ApplicationContext; | ||||||||||||||||||||||
| import org.springframework.stereotype.Service; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| @Slf4j | ||||||||||||||||||||||
| @Service | ||||||||||||||||||||||
| @RequiredArgsConstructor | ||||||||||||||||||||||
| public class NotifyService { | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| private final NotifyClientAdapter notifier; | ||||||||||||||||||||||
| private final ProfileJpaRepository profileJpaRepository; | ||||||||||||||||||||||
| private final ApplicationContext applicationContext; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| public void notify(NotifyEvent event) { | ||||||||||||||||||||||
| NotifyStrategy strategy = getNotifyStrategy(event.status().getStrategyName()); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| ProfileJpaEntity profile = profileJpaRepository.findByUserId(event.targetId()) | ||||||||||||||||||||||
| .orElseThrow(() -> new CustomRuntimeException(ErrorCode.PROFILE_NOT_FOUND)); | ||||||||||||||||||||||
| String parsedPhoneNumber = profile.getPhoneNumber().replaceAll("-", ""); | ||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add validation for phone number processing. The current implementation assumes the phone number always contains hyphens and doesn't validate the format. Consider adding validation. - String parsedPhoneNumber = profile.getPhoneNumber().replaceAll("-", "");
+ String phoneNumber = profile.getPhoneNumber();
+ if (phoneNumber == null || phoneNumber.trim().isEmpty()) {
+ throw new CustomRuntimeException(ErrorCode.INVALID_PHONE_NUMBER);
+ }
+ String parsedPhoneNumber = phoneNumber.replaceAll("-", "");📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| NotifyEventRequest request = strategy.apply(parsedPhoneNumber, event); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| notifier.send(request); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| private NotifyStrategy getNotifyStrategy(String strategyName) { | ||||||||||||||||||||||
| return (NotifyStrategy) applicationContext.getBean(strategyName); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
Comment on lines
+37
to
+39
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Add error handling for missing strategy beans. The current implementation will throw a private NotifyStrategy getNotifyStrategy(String strategyName) {
- return (NotifyStrategy) applicationContext.getBean(strategyName);
+ try {
+ return (NotifyStrategy) applicationContext.getBean(strategyName);
+ } catch (NoSuchBeanDefinitionException e) {
+ throw new CustomRuntimeException(ErrorCode.STRATEGY_NOT_FOUND);
+ }
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| } | ||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package life.mosu.mosuserver.domain.applicationschool; | ||
|
|
||
| import java.time.LocalDate; | ||
| import life.mosu.mosuserver.domain.application.Lunch; | ||
|
|
||
| public record ApplicationSchoolNotifyProjection( | ||
| String paymentKey, | ||
| LocalDate examDate, | ||
| String schoolName, | ||
| Lunch lunch | ||
| ) { | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| package life.mosu.mosuserver.domain.applicationschool; | ||
|
|
||
| import java.time.LocalDate; | ||
|
|
||
| public record OneWeekNotifyProjection( | ||
| String paymentKey, | ||
| LocalDate examDate, | ||
| String schoolName | ||
| ) { | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,20 @@ | ||
| package life.mosu.mosuserver.domain.refund; | ||
|
|
||
| import org.springframework.data.jpa.repository.JpaRepository; | ||
| import org.springframework.data.jpa.repository.Query; | ||
|
|
||
| public interface RefundJpaRepository extends JpaRepository<RefundJpaEntity, Long> { | ||
|
|
||
| @Query(""" | ||
| SELECT | ||
| p.paymentKey AS paymentKey, | ||
| a.examDate AS examDate, | ||
| p.paymentMethod AS paymentMethod, | ||
| r.reason AS reason | ||
| FROM RefundJpaEntity r | ||
| LEFT JOIN PaymentJpaEntity p ON r.applicationSchoolId = p.applicationSchoolId | ||
| LEFT JOIN ApplicationSchoolJpaEntity a ON r.applicationSchoolId = a.id | ||
| WHERE r.applicationSchoolId = :applicationSchoolId | ||
| """) | ||
|
Comment on lines
+8
to
+18
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The query for @Query("""
SELECT
p.paymentKey AS paymentKey,
a.examDate AS examDate,
a.schoolName AS schoolName,
p.paymentMethod AS paymentMethod,
r.reason AS reason
FROM RefundJpaEntity r
LEFT JOIN PaymentJpaEntity p ON r.applicationSchoolId = p.applicationSchoolId
LEFT JOIN ApplicationSchoolJpaEntity a ON r.applicationSchoolId = a.id
WHERE r.applicationSchoolId = :applicationSchoolId
""") |
||
| RefundNotifyProjection findRefundByApplicationSchoolId(Long applicationSchoolId); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| package life.mosu.mosuserver.domain.refund; | ||
|
|
||
| import java.time.LocalDate; | ||
| import life.mosu.mosuserver.domain.payment.PaymentMethod; | ||
|
|
||
| public record RefundNotifyProjection( | ||
| String paymentKey, | ||
| LocalDate examDate, | ||
| String schoolName, | ||
| PaymentMethod paymentMethod, | ||
| String reason | ||
| // TODO: 환불 금액 추가 | ||
| ) { | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| package life.mosu.mosuserver.domain.school; | ||
|
|
||
| import java.time.LocalDate; | ||
| import java.util.List; | ||
| import org.apache.commons.lang3.tuple.Triple; | ||
|
|
||
| public interface SchoolQueryRepository { | ||
|
|
||
| List<Long> findSchoolsByConditions( | ||
| List<Triple<String, Area, LocalDate>> conditions); | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,38 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| package life.mosu.mosuserver.domain.school; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.querydsl.core.BooleanBuilder; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import com.querydsl.jpa.impl.JPAQueryFactory; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.time.LocalDate; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import java.util.List; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import lombok.RequiredArgsConstructor; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import org.apache.commons.lang3.tuple.Triple; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import org.springframework.stereotype.Repository; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Repository | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @RequiredArgsConstructor | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public class SchoolQueryRepositoryImpl implements SchoolQueryRepository { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| private final JPAQueryFactory queryFactory; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| @Override | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| public List<Long> findSchoolsByConditions( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| List<Triple<String, Area, LocalDate>> conditions) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| BooleanBuilder builder = new BooleanBuilder(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (Triple<String, Area, LocalDate> cond : conditions) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| builder.or( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| QSchoolJpaEntity.schoolJpaEntity.schoolName.eq(cond.getLeft()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .and(QSchoolJpaEntity.schoolJpaEntity.area.eq(cond.getMiddle())) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .and(QSchoolJpaEntity.schoolJpaEntity.examDate.eq(cond.getRight())) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return queryFactory | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .select(QSchoolJpaEntity.schoolJpaEntity.id) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .from(QSchoolJpaEntity.schoolJpaEntity) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .where(builder) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .fetch(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+18
to
+35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider adding validation for empty conditions list. The method doesn't handle the case where the conditions list is empty, which would result in a query with no WHERE clause, potentially returning all schools. @Override
public List<Long> findSchoolsByConditions(
List<Triple<String, Area, LocalDate>> conditions) {
+ if (conditions == null || conditions.isEmpty()) {
+ return List.of();
+ }
+
BooleanBuilder builder = new BooleanBuilder();📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,16 @@ | ||||||||||||||||||||||||||
| package life.mosu.mosuserver.global.annotation; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| import java.lang.annotation.ElementType; | ||||||||||||||||||||||||||
| import java.lang.annotation.Retention; | ||||||||||||||||||||||||||
| import java.lang.annotation.RetentionPolicy; | ||||||||||||||||||||||||||
| import java.lang.annotation.Target; | ||||||||||||||||||||||||||
| import org.springframework.context.event.EventListener; | ||||||||||||||||||||||||||
| import org.springframework.scheduling.annotation.Async; | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| @Target(ElementType.METHOD) | ||||||||||||||||||||||||||
| @Retention(RetentionPolicy.RUNTIME) | ||||||||||||||||||||||||||
| @Async | ||||||||||||||||||||||||||
| @EventListener | ||||||||||||||||||||||||||
| public @interface ReactiveEventListener { | ||||||||||||||||||||||||||
|
Comment on lines
+10
to
+14
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Annotation name & meta-configuration are misleading The composed annotation wires Suggestions: -@Target(ElementType.METHOD)
-@Retention(RetentionPolicy.RUNTIME)
-@Async
-@EventListener
-public @interface ReactiveEventListener {
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Async
+@EventListener
+public @interface AsyncEventListener { // clearer intent
}• Add 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| package life.mosu.mosuserver.global.config; | ||
|
|
||
| import org.springframework.context.MessageSource; | ||
| import org.springframework.context.annotation.Bean; | ||
| import org.springframework.context.annotation.Configuration; | ||
| import org.springframework.context.support.ReloadableResourceBundleMessageSource; | ||
|
|
||
| @Configuration | ||
| public class MessageSourceConfig { | ||
|
|
||
| @Bean | ||
| public MessageSource messageSource() { | ||
| ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); | ||
| messageSource.setBasename("classpath:messages"); | ||
| messageSource.setDefaultEncoding("UTF-8"); | ||
| return messageSource; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,17 @@ | ||||||||||||||||||||||||||||||||||||
| package life.mosu.mosuserver.global.config; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| import org.springframework.context.annotation.Bean; | ||||||||||||||||||||||||||||||||||||
| import org.springframework.context.annotation.Configuration; | ||||||||||||||||||||||||||||||||||||
| import org.springframework.http.MediaType; | ||||||||||||||||||||||||||||||||||||
| import org.springframework.web.reactive.function.client.WebClient; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| @Configuration | ||||||||||||||||||||||||||||||||||||
| public class WebClientConfig { | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| @Bean | ||||||||||||||||||||||||||||||||||||
| public WebClient webClient() { | ||||||||||||||||||||||||||||||||||||
| return WebClient.builder() | ||||||||||||||||||||||||||||||||||||
| .defaultHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE) | ||||||||||||||||||||||||||||||||||||
| .build(); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+11
to
+16
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Set sensible timeouts & use header constants A bare - return WebClient.builder()
- .defaultHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE)
- .build();
+ return WebClient.builder()
+ .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
+ .clientConnector(new ReactorClientHttpConnector(
+ HttpClient.create()
+ .responseTimeout(Duration.ofSeconds(5))
+ .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000)
+ ))
+ .build();• Use 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.