# Research: Auto-Delete Expired Events **Feature**: 013-auto-delete-expired | **Date**: 2026-03-09 ## Deletion Strategy - **Decision**: Direct native SQL DELETE query via Spring Data JPA `@Query`. - **Rationale**: Simplest approach. No entity loading overhead. The existing `ON DELETE CASCADE` FK constraint on `fk_rsvps_event_id` (migration `003-create-rsvps-table.xml`) handles cascading deletion of RSVPs automatically. The existing `idx_events_expiry_date` index ensures the WHERE clause is efficient. - **Alternatives considered**: - JPA repository `deleteAll(findExpired())`: Loads entities into memory first, unnecessary overhead. - Database-level cron (`pg_cron`): Less portable, adds external dependency. - Soft delete with lazy cleanup: Over-engineered for fete's scale and privacy goals. - No deletion (filter only): Contradicts privacy-by-design principle. ## Scheduling Mechanism - **Decision**: Spring `@Scheduled(cron = ...)` annotation. - **Rationale**: Already available in Spring Boot, no additional dependencies. Simple, declarative, well-tested. - **Alternatives considered**: - Quartz Scheduler: Too heavy for a single daily job. - External cron (OS-level): Requires separate process management, harder to test. ## Transaction Behavior - **Decision**: Single transaction for the DELETE statement. - **Rationale**: A single `DELETE FROM events WHERE expiry_date < CURRENT_DATE` is atomic. If the DB connection drops mid-execution, the transaction rolls back and no events are partially deleted. The next run picks up all expired events. ## Enabling @Scheduled - **Decision**: Add `@EnableScheduling` to `FeteApplication.java`. - **Rationale**: Simplest approach. Only one scheduled job exists, no need for a separate config class.