# Feature Specification: Automatic Data Deletion After Expiry Date **Feature**: `018-data-deletion` **Created**: 2026-03-06 **Status**: Draft **Source**: Migrated from spec/userstories.md ## User Scenarios & Testing ### User Story 1 - Automatic cleanup of expired event data (Priority: P1) As a guest, I want all event data — including my RSVP and any other stored personal information — to be automatically and permanently deleted after the event's expiry date, so that I can trust that data I submitted is not retained on the server longer than necessary. **Why this priority**: This is a privacy guarantee, not merely a housekeeping task. The mandatory expiry date in US-1 is only meaningful if the server actually enforces deletion. Without this story, the expiry date is a lie. **Independent Test**: Can be tested by creating an event with a near-future expiry date, submitting an RSVP, waiting for expiry, and verifying that the event's public URL returns "event not found" and no data remains accessible. **Acceptance Scenarios**: 1. **Given** an event whose expiry date has passed, **When** the cleanup process runs, **Then** the event record and all associated data (RSVPs, update messages, field-change metadata, header images, cancellation state) are permanently deleted from the server. 2. **Given** an event that has been deleted by the cleanup process, **When** a guest navigates to the event's public URL, **Then** the server returns a clear "event not found" response with no partial data or error traces. 3. **Given** a deletion event, **When** the cleanup process deletes data, **Then** no log entry records the names, RSVPs, or any personal data of the deleted event's guests — the deletion is silent from a logging perspective. 4. **Given** the cleanup process, **When** it runs, **Then** it runs automatically without manual operator intervention (e.g. via a scheduled job or on-request lazy cleanup triggered by access attempts). --- ### User Story 2 - Expiry date extension delays deletion (Priority: P2) As an event organizer, I want to be able to extend the expiry date of my event (via US-5) and have the deletion be deferred accordingly, so that I can keep my event data available for longer when needed. **Why this priority**: Ensures US-5 (edit expiry date) and US-12 (deletion) work together correctly — the cleanup must always use the current stored expiry date, not the original one. **Independent Test**: Can be tested by creating an event, extending its expiry date before expiry passes, and verifying that the event data is not deleted until the new expiry date. **Acceptance Scenarios**: 1. **Given** an event whose expiry date was extended via US-5 before the original expiry passed, **When** the cleanup process runs after the original date but before the new date, **Then** the event data is not deleted. 2. **Given** an event whose expiry date was extended, **When** the new expiry date passes and the cleanup process runs, **Then** the event and all associated data are deleted. --- ### User Story 3 - Cleanup does not trigger early (Priority: P2) As a guest, I want my event data to be retained until the expiry date has fully passed, so that I can access the event page right up until expiry without unexpected data loss. **Why this priority**: Ensures correctness — data must not be deleted prematurely. **Independent Test**: Can be tested by verifying that an event with an expiry date set to tomorrow remains fully accessible today. **Acceptance Scenarios**: 1. **Given** an event whose expiry date is today but has not yet passed, **When** a guest accesses the event page, **Then** the event data is still served normally. 2. **Given** an event whose expiry date passed yesterday, **When** the cleanup process runs, **Then** the event and all associated data are deleted. --- ### Edge Cases - What happens if the cleanup process fails mid-run (e.g. server crash)? The next run must safely re-attempt deletion without corrupting partial state. - What happens if multiple cleanup runs overlap? The process must be idempotent — deleting an already-deleted event must not cause errors. - LocalStorage entries on guests' devices are unaffected by server-side deletion — this is intentional. The app handles the "event not found" response gracefully (US-2, US-7). - If a stored header image file is missing on disk at deletion time (e.g. corrupted storage), the cleanup must still complete and delete the database record. ## Requirements ### Functional Requirements - **FR-001**: The server MUST run a periodic cleanup process that automatically deletes all data associated with events whose expiry date has passed. - **FR-002**: The cleanup MUST delete the event record along with all associated data: RSVPs, update messages (US-10a), field-change metadata (US-9), stored header images (US-16) [deferred until US-16 is implemented], and cancellation state (US-18 if applicable). - **FR-003**: After deletion, the event's public URL MUST return a clear "event not found" response — no partial data is ever served. - **FR-004**: The cleanup process MUST run automatically without manual operator intervention (e.g. a scheduled job, Spring `@Scheduled`, or on-request lazy cleanup triggered by access attempts). - **FR-005**: The cleanup MUST NOT log the names, RSVPs, or any personal data of deleted events — deletion is silent from a logging perspective. - **FR-006**: The cleanup MUST always use the current stored expiry date when determining whether an event is eligible for deletion — extending the expiry date via US-5 before expiry passes delays deletion accordingly. - **FR-007**: The cleanup MUST NOT be triggered early — data is retained until the expiry date has passed, not before. - **FR-008**: The cleanup process MUST be idempotent — re-running it against already-deleted events must not cause errors. ### Key Entities - **Event (expiry_date)**: The `expiry_date` field on the Event entity determines when the event becomes eligible for deletion. It is updated by US-5 (edit event details). - **Cleanup Job**: A background process (not a user-facing entity) responsible for identifying and deleting expired events and all their associated data. ## Success Criteria ### Measurable Outcomes - **SC-001**: An event with a passed expiry date returns "event not found" from the server within one cleanup cycle of the expiry. - **SC-002**: All associated data (RSVPs, update messages, metadata, images) is deleted atomically with the event record — no orphaned records remain after a successful cleanup run. - **SC-003**: No PII (names, RSVP choices) appears in server logs during or after the deletion process. - **SC-004**: Extending an event's expiry date via US-5 correctly defers deletion — verified by querying the database after the original expiry would have triggered cleanup. - **SC-005**: The cleanup process completes successfully even if a stored header image file is missing on disk (resilient to partial storage failures).