Files
fete/specs/014-cancel-rsvp/data-model.md
nitrix 41bb17d5c9
All checks were successful
CI / backend-test (push) Successful in 59s
CI / frontend-test (push) Successful in 24s
CI / frontend-e2e (push) Successful in 1m18s
CI / build-and-publish (push) Has been skipped
Add cancel RSVP feature (backend DELETE endpoint + frontend UI)
Allows guests to cancel their RSVP via a DELETE endpoint using their
guestToken. Frontend shows cancel button in RsvpBar and clears local
storage on success. Includes unit tests, integration tests, and E2E spec.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 17:45:37 +01:00

2.4 KiB

Data Model: Cancel RSVP

Feature: 014-cancel-rsvp | Date: 2026-03-09

Entities

RSVP (existing — no schema changes)

Field Type Constraints Notes
id BIGSERIAL PK, auto-generated Internal DB ID, never exposed
rsvp_token UUID UNIQUE, NOT NULL Bearer credential for the guest
event_id BIGINT FK → events.id, NOT NULL Links RSVP to event
name VARCHAR(100) NOT NULL Guest display name

No migration needed. The cancel feature only deletes existing rows — no new columns or tables.

State Transitions

┌──────────┐    POST /events/{token}/rsvps    ┌──────────┐
│ No RSVP  │ ──────────────────────────────► │ Attending │
│ (guest)  │ ◄────────────────────────────── │  (guest)  │
└──────────┘  DELETE /events/{token}/rsvps/   └──────────┘
                    {rsvpToken}

The transition is fully reversible: after cancellation, the guest can create a new RSVP (new token generated).

Client-Side Storage (localStorage)

StoredEvent (existing interface — no changes)

interface StoredEvent {
  eventToken: string      // always present
  title: string           // always present
  dateTime: string        // always present
  organizerToken?: string // present if organizer
  rsvpToken?: string      // present if RSVP'd — CLEARED on cancel
  rsvpName?: string       // present if RSVP'd — CLEARED on cancel
}

Cancel Effects on localStorage

Action rsvpToken rsvpName Event in list
Cancel from detail view Removed Removed Kept
Remove from event list Removed Removed Removed

Repository Changes

RsvpRepository (domain port)

New method:

/**
 * Delete an RSVP by event ID and RSVP token.
 * @return true if a record was deleted, false if not found
 */
boolean deleteByEventIdAndRsvpToken(Long eventId, RsvpToken rsvpToken);

RsvpJpaRepository

New method:

long deleteByEventIdAndRsvpToken(Long eventId, UUID rsvpToken);

Returns count of deleted rows (0 or 1). Spring Data JPA auto-implements this derived query.