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

6.9 KiB

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