Files
fete/specs/018-data-deletion/spec.md
nitrix 6aeb4b8bca Migrate project artifacts to spec-kit format
- Move cross-cutting docs (personas, design system, implementation phases,
  Ideen.md) to .specify/memory/
- Move cross-cutting research and plans to .specify/memory/research/ and
  .specify/memory/plans/
- Extract 5 setup tasks from spec/setup-tasks.md into individual
  specs/001-005/spec.md files with spec-kit template format
- Extract 20 user stories from spec/userstories.md into individual
  specs/006-026/spec.md files with spec-kit template format
- Relocate feature-specific research and plan docs into specs/[feature]/
- Add spec-kit constitution, templates, scripts, and slash commands
- Slim down CLAUDE.md to Claude-Code-specific config, delegate principles
  to .specify/memory/constitution.md
- Update ralph.sh with stream-json output and per-iteration logging
- Delete old spec/ and docs/agents/ directories
- Gitignore Ralph iteration JSONL logs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-06 20:19:41 +01:00

91 lines
6.9 KiB
Markdown

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