# Data Model: Cancel Event from Event List

**Date**: 2026-03-12 | **Branch**: `018-cancel-event-list`

## No New Entities

This feature introduces no new entities, fields, or relationships. All required data structures already exist.

## Existing Entities Used

### StoredEvent (frontend localStorage)

| Field | Type | Notes |
|-------|------|-------|
| eventToken | string (UUID) | Used as path param for cancel API |
| organizerToken | string (UUID) \| undefined | Present only for organizer role; used as query param |
| rsvpToken | string (UUID) \| undefined | Present only for attendee role |
| rsvpName | string \| undefined | Attendee display name |
| title | string | Event title for dialog context |
| dateTime | string | Event date/time |

### Role Detection (derived, not stored)

| Role | Condition | Delete Action |
|------|-----------|---------------|
| organizer | `organizerToken` present | PATCH cancel-event API |
| attendee | `rsvpToken` present (no organizerToken) | DELETE cancel-rsvp API |
| watcher | neither token present | Direct localStorage removal |

### API Contracts Used

| Endpoint | Method | Auth | Body | Success | Already Cancelled |
|----------|--------|------|------|---------|-------------------|
| `/events/{eventToken}` | PATCH | `?organizerToken=...` | `{ cancelled: true }` | 204 | 409 (treat as success) |
| `/events/{eventToken}/rsvps/{rsvpToken}` | DELETE | rsvpToken in path | — | 204 | 204 (idempotent) |
