-
Notifications
You must be signed in to change notification settings - Fork 0
Fix/task schedule 분리로 인한 이벤트 처리 갱신 #18
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
The head ref may contain hidden characters: "fix/task-schedule-\uBD84\uB9AC\uB85C-\uC778\uD55C-\uC774\uBCA4\uD2B8-\uCC98\uB9AC-\uAC31\uC2E0"
Changes from all commits
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 | ||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -33,7 +33,12 @@ public ScheduleNotificationService(UpcomingScheduleNotificationRepository notifi | |||||||||||||||||||||||||||||||||||||||||||||||||||
| public void handleUpcomingUpdated(UpcomingUpdatedCommand command) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| notificationRepository.findByScheduleIdAndOwnerId(command.scheduleId(), command.ownerId()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| .ifPresentOrElse( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| existing -> existing.updateScheduleStartTime(resolveScheduleStartTime(command, existing), command.idempotentKey()), | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| existing -> notificationRepository.updateScheduleStartTimeAndIdempotentKey( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| command.scheduleId(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| command.ownerId(), | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| resolveScheduleStartTime(command, existing), | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| command.idempotentKey() | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ), | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+36
to
+41
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| existing -> notificationRepository.updateScheduleStartTimeAndIdempotentKey( | |
| command.scheduleId(), | |
| command.ownerId(), | |
| resolveScheduleStartTime(command, existing), | |
| command.idempotentKey() | |
| ), | |
| existing -> { | |
| int updatedRows = notificationRepository.updateScheduleStartTimeAndIdempotentKey( | |
| command.scheduleId(), | |
| command.ownerId(), | |
| resolveScheduleStartTime(command, existing), | |
| command.idempotentKey() | |
| ); | |
| if (updatedRows == 0) { | |
| // 동시 삭제 등으로 업데이트 대상이 사라진 경우, 신규로 생성하여 업서트 보장 | |
| notificationRepository.save( | |
| buildNotification( | |
| command.ownerId(), | |
| command.scheduleId(), | |
| command.idempotentKey(), | |
| toStringValue(command.newUpcomingTime()) | |
| ) | |
| ); | |
| } | |
| }, |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,11 +1,31 @@ | ||
| package me.pinitnotification.infrastructure.persistence.notification; | ||
|
|
||
| import org.springframework.data.jpa.repository.JpaRepository; | ||
| import org.springframework.data.jpa.repository.Modifying; | ||
| import org.springframework.data.jpa.repository.Query; | ||
| import org.springframework.data.repository.query.Param; | ||
|
|
||
| import java.util.Optional; | ||
| import java.util.UUID; | ||
|
|
||
| public interface UpcomingScheduleNotificationJpaRepository extends JpaRepository<UpcomingScheduleNotificationEntity, Long> { | ||
| public interface UpcomingScheduleNotificationJpaRepository extends JpaRepository<UpcomingScheduleNotificationEntity, UUID> { | ||
| Optional<UpcomingScheduleNotificationEntity> findByScheduleIdAndOwnerId(Long scheduleId, Long ownerId); | ||
| boolean existsByScheduleIdAndOwnerId(Long scheduleId, Long ownerId); | ||
|
|
||
| @Modifying(flushAutomatically = true, clearAutomatically = true) | ||
| @Query(""" | ||
| UPDATE UpcomingScheduleNotificationEntity n | ||
| SET n.scheduleStartTime = :scheduleStartTime, | ||
| n.idempotentKey = :idempotentKey | ||
| WHERE n.scheduleId = :scheduleId | ||
| AND n.ownerId = :ownerId | ||
| """) | ||
| int updateScheduleStartTimeAndIdempotentKey( | ||
| @Param("scheduleId") Long scheduleId, | ||
| @Param("ownerId") Long ownerId, | ||
| @Param("scheduleStartTime") String scheduleStartTime, | ||
| @Param("idempotentKey") String idempotentKey | ||
| ); | ||
|
|
||
| void deleteByScheduleIdAndOwnerId(Long scheduleId, Long ownerId); | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -2,13 +2,17 @@ | |||||
|
|
||||||
| import me.pinitnotification.domain.notification.UpcomingScheduleNotification; | ||||||
| import me.pinitnotification.domain.notification.UpcomingScheduleNotificationRepository; | ||||||
| import org.slf4j.Logger; | ||||||
| import org.slf4j.LoggerFactory; | ||||||
| import org.springframework.stereotype.Repository; | ||||||
|
|
||||||
| import java.util.List; | ||||||
| import java.util.Optional; | ||||||
|
|
||||||
| @Repository | ||||||
| public class UpcomingScheduleNotificationRepositoryAdapter implements UpcomingScheduleNotificationRepository { | ||||||
| private static final Logger log = LoggerFactory.getLogger(UpcomingScheduleNotificationRepositoryAdapter.class); | ||||||
|
|
||||||
| private final UpcomingScheduleNotificationJpaRepository jpaRepository; | ||||||
|
|
||||||
| public UpcomingScheduleNotificationRepositoryAdapter(UpcomingScheduleNotificationJpaRepository jpaRepository) { | ||||||
|
|
@@ -39,6 +43,14 @@ public UpcomingScheduleNotification save(UpcomingScheduleNotification notificati | |||||
| return toDomain(saved); | ||||||
| } | ||||||
|
|
||||||
| @Override | ||||||
| public void updateScheduleStartTimeAndIdempotentKey(Long scheduleId, Long ownerId, String scheduleStartTime, String idempotentKey) { | ||||||
| int updatedRows = jpaRepository.updateScheduleStartTimeAndIdempotentKey(scheduleId, ownerId, scheduleStartTime, idempotentKey); | ||||||
| if (updatedRows == 0) { | ||||||
| log.debug("Skip updating notification. scheduleId={}, ownerId={} not found", scheduleId, ownerId); | ||||||
|
||||||
| log.debug("Skip updating notification. scheduleId={}, ownerId={} not found", scheduleId, ownerId); | |
| log.warn("Skip updating notification because target not found. scheduleId={}, ownerId={}", scheduleId, ownerId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(1) 문제점: AsyncAPI 스키마의 string format을 표준
date-time에서designatedStartTime-time로 변경했는데, 이 값은 OpenAPI/AsyncAPI tooling에서 일반적으로 인식되는 포맷이 아니고 문서 내에서도 별도 정의가 없습니다.(2) 영향: 문서를 기반으로 한 검증/코드 생성/스키마 호환성 체크가 실패하거나, 소비자가 RFC3339(date-time)로 해석해야 하는 필드를 잘못 이해할 수 있습니다.
(3) 수정 제안: 실제 값이 RFC3339라면
format: date-time을 유지하고, 의미 차이는 description 또는x-...커스텀 필드로 보강해 주세요(커스텀 format을 쓰려면 문서 상단에 정의/설명을 추가).