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>
3.7 KiB
3.7 KiB
Tasks: Auto-Delete Expired Events
Input: Design documents from /specs/013-auto-delete-expired/
Prerequisites: plan.md, spec.md, research.md, data-model.md
Tests: Included — constitution mandates TDD (Principle II).
Organization: Single user story (US1), so phases are compact.
Format: [ID] [P?] [Story] Description
- [P]: Can run in parallel (different files, no dependencies)
- [Story]: Which user story this task belongs to (e.g., US1)
- Include exact file paths in descriptions
Phase 1: Setup
Purpose: Enable Spring scheduling in the application.
- T001 Add
@EnableSchedulingannotation tobackend/src/main/java/de/fete/FeteApplication.java
Phase 2: User Story 1 — Automatic Cleanup of Expired Events (Priority: P1)
Goal: A daily scheduled job deletes all events whose expiryDate is in the past, including cascaded RSVPs.
Independent Test: Create events with past expiry dates, trigger the cleanup job, verify events and RSVPs are gone.
Tests for User Story 1
NOTE: Write these tests FIRST, ensure they FAIL before implementation
- T002 [P] [US1] Unit test for
ExpiredEventCleanupJobinbackend/src/test/java/de/fete/application/service/ExpiredEventCleanupJobTest.java— verify job callsdeleteExpired()on repository and logs the count - T003 [P] [US1] Integration test for native DELETE query in
backend/src/test/java/de/fete/adapter/out/persistence/EventPersistenceAdapterIntegrationTest.java— verify expired events + RSVPs are deleted, non-expired events survive
Implementation for User Story 1
- T004 [P] [US1] Add
int deleteExpired()method to port interfacebackend/src/main/java/de/fete/domain/port/out/EventRepository.java - T005 [P] [US1] Add native
@Modifying @Query("DELETE FROM events WHERE expiry_date < CURRENT_DATE")method tobackend/src/main/java/de/fete/adapter/out/persistence/EventJpaRepository.java - T006 [US1] Implement
deleteExpired()inbackend/src/main/java/de/fete/adapter/out/persistence/EventPersistenceAdapter.java— delegates to JPA repository native query - T007 [US1] Create
ExpiredEventCleanupJobwith@Scheduled(cron = "0 0 3 * * *")inbackend/src/main/java/de/fete/application/service/ExpiredEventCleanupJob.java— callsdeleteExpired(), logs count at INFO level
Checkpoint: All tests pass. Expired events are automatically deleted daily at 03:00.
Dependencies & Execution Order
Phase Dependencies
- Setup (Phase 1): No dependencies — can start immediately
- User Story 1 (Phase 2): Depends on Setup completion
Within User Story 1
- T002, T003 (tests) can run in parallel — write first, must fail (RED)
- T004, T005 (port + JPA query) can run in parallel — different files
- T006 depends on T004 + T005 (adapter implements port, delegates to JPA)
- T007 depends on T006 (job calls adapter via port)
- After T007: all tests should pass (GREEN)
Parallel Opportunities
T002 ──┐
├── (tests written, failing)
T003 ──┘
T004 ──┐
├── T006 ── T007 ── (all tests green)
T005 ──┘
Implementation Strategy
MVP (this is the MVP — single story)
- T001: Enable scheduling
- T002 + T003: Write failing tests (RED)
- T004 + T005: Port interface + native query (parallel)
- T006: Adapter implementation
- T007: Scheduled job
- Verify all tests pass (GREEN)
- Done — commit and ship
Notes
- Total tasks: 7
- User Story 1 tasks: 6 (T002–T007)
- Setup tasks: 1 (T001)
- Parallel opportunities: T002||T003, T004||T005
- No frontend changes needed
- No API/OpenAPI changes needed
- No new migrations needed (existing schema + FK constraints sufficient)