# 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.
