feat(gift): 전달불가 선물의 배송 개인정보를 만료 후 파기한다

This commit is contained in:
2026-11-01 14:33:35 +09:00
parent 1a544ddd45
commit 373b11348b
4 changed files with 129 additions and 78 deletions
@@ -108,17 +108,26 @@ interface GiftRepository : JpaRepository<Gift, Long>, GiftLockRepository {
"""
select g
from Gift g
where g.status = kr.co.vividnext.sodalive.v2.gift.domain.GiftStatus.DELIVERED
and exists (
select d.id
from GiftDelivery d
where d.giftId = g.id
and d.deliveredAt is not null
and d.deliveredAt <= :cutoff
)
where exists (
select d.id
from GiftDelivery d
where d.giftId = g.id
and (
(
g.status = kr.co.vividnext.sodalive.v2.gift.domain.GiftStatus.DELIVERED
and d.deliveredAt is not null
and d.deliveredAt <= :cutoff
)
or (
g.status = kr.co.vividnext.sodalive.v2.gift.domain.GiftStatus.UNDELIVERABLE
and d.undeliverableAt is not null
and d.undeliverableAt <= :cutoff
)
)
)
"""
)
fun findDeliveredGiftsWithDeliveryBeforeOrAt(@Param("cutoff") cutoff: LocalDateTime): List<Gift>
fun findGiftsWithPersonalDataRetentionExpired(@Param("cutoff") cutoff: LocalDateTime): List<Gift>
@Query(
"""
@@ -92,23 +92,23 @@ class GiftScheduler(
@Scheduled(cron = "0 20 * * * *", zone = "Asia/Seoul")
@Transactional
fun runDeliveredGiftPersonalDataErasure() {
val lock = redissonClient.getLock(DELIVERED_GIFT_PERSONAL_DATA_ERASURE_LOCK_KEY)
fun runGiftPersonalDataErasure() {
val lock = redissonClient.getLock(GIFT_PERSONAL_DATA_ERASURE_LOCK_KEY)
if (!lock.tryLock(0, -1, TimeUnit.SECONDS)) {
return
}
try {
eraseDeliveredGiftPersonalData(LocalDateTime.now())
eraseGiftPersonalData(LocalDateTime.now())
} finally {
unlockAfterTransaction(lock)
}
}
@Transactional
fun eraseDeliveredGiftPersonalData(now: LocalDateTime): Int {
fun eraseGiftPersonalData(now: LocalDateTime): Int {
val cutoff = now.minusDays(7)
val expiredGifts = giftRepository.findDeliveredGiftsWithDeliveryBeforeOrAt(cutoff)
val expiredGifts = giftRepository.findGiftsWithPersonalDataRetentionExpired(cutoff)
return expiredGifts.count { gift ->
val delivery = requireNotNull(giftDeliveryRepository.findByGiftId(requireNotNull(gift.id)))
@@ -218,7 +218,7 @@ class GiftScheduler(
const val DEADLINE_REMINDER_HOURS = 24L
const val EXPIRED_TRACKING_REGISTRATION_GIFTS_LOCK_KEY = "lock:gift-expired-tracking-registration-cancellation"
const val EXPIRED_RECIPIENT_ADDRESS_GIFTS_LOCK_KEY = "lock:gift-expired-recipient-address-undeliverable"
const val DELIVERED_GIFT_PERSONAL_DATA_ERASURE_LOCK_KEY = "lock:gift-delivered-personal-data-erasure"
const val GIFT_PERSONAL_DATA_ERASURE_LOCK_KEY = "lock:gift-delivered-personal-data-erasure"
const val DEADLINE_REMINDER_GIFTS_LOCK_KEY = "lock:gift-deadline-reminders"
const val EXPIRED_RECIPIENT_ADDRESS_REASON = "배송지 미입력 기한 초과"
}