Auto-delete expired events via daily scheduled cleanup job
All checks were successful
CI / backend-test (push) Successful in 58s
CI / frontend-test (push) Successful in 23s
CI / frontend-e2e (push) Successful in 1m10s
CI / build-and-publish (push) Has been skipped

Adds a Spring @Scheduled job (daily at 03:00) that deletes all events
whose expiry_date is before CURRENT_DATE using a native SQL DELETE.
RSVPs are cascade-deleted via the existing FK constraint.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-09 21:58:35 +01:00
parent 2a6a658df9
commit 4bfaee685c
14 changed files with 499 additions and 0 deletions

View File

@@ -0,0 +1,81 @@
package de.fete.adapter.out.persistence;
import static org.assertj.core.api.Assertions.assertThat;
import de.fete.TestcontainersConfig;
import de.fete.domain.model.Event;
import de.fete.domain.model.EventToken;
import de.fete.domain.model.OrganizerToken;
import de.fete.domain.port.out.EventRepository;
import java.time.LocalDate;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Import;
import org.springframework.transaction.annotation.Transactional;
@SpringBootTest
@Import(TestcontainersConfig.class)
@Transactional
class EventPersistenceAdapterIntegrationTest {
@Autowired
private EventRepository eventRepository;
@Test
void deleteExpiredRemovesExpiredEvents() {
Event expired = buildEvent("Expired Party", LocalDate.now().minusDays(1));
eventRepository.save(expired);
int deleted = eventRepository.deleteExpired();
assertThat(deleted).isGreaterThanOrEqualTo(1);
}
@Test
void deleteExpiredKeepsNonExpiredEvents() {
Event future = buildEvent("Future Party", LocalDate.now().plusDays(30));
Event saved = eventRepository.save(future);
eventRepository.deleteExpired();
assertThat(eventRepository.findByEventToken(saved.getEventToken())).isPresent();
}
@Test
void deleteExpiredKeepsEventsExpiringToday() {
Event today = buildEvent("Today Party", LocalDate.now());
Event saved = eventRepository.save(today);
eventRepository.deleteExpired();
assertThat(eventRepository.findByEventToken(saved.getEventToken())).isPresent();
}
@Test
void deleteExpiredReturnsZeroWhenNoneExpired() {
// Only save a future event
buildEvent("Future Only", LocalDate.now().plusDays(60));
int deleted = eventRepository.deleteExpired();
assertThat(deleted).isGreaterThanOrEqualTo(0);
}
private Event buildEvent(String title, LocalDate expiryDate) {
var event = new Event();
event.setEventToken(EventToken.generate());
event.setOrganizerToken(OrganizerToken.generate());
event.setTitle(title);
event.setDescription("Test description");
event.setDateTime(OffsetDateTime.of(2026, 6, 15, 20, 0, 0, 0, ZoneOffset.ofHours(2)));
event.setTimezone(ZoneId.of("Europe/Berlin"));
event.setLocation("Test Location");
event.setExpiryDate(expiryDate);
event.setCreatedAt(OffsetDateTime.now());
return event;
}
}