Add organizer cancel-event flow to EventList
All checks were successful
CI / backend-test (push) Successful in 58s
CI / frontend-test (push) Successful in 26s
CI / frontend-e2e (push) Successful in 1m35s
CI / build-and-publish (push) Has been skipped

Organizers can now cancel events directly from the event list via the
existing PATCH /events/{eventToken} API. The confirmation dialog shows
role-differentiated messaging: "Cancel event?" with a severity warning
for organizers vs. "Remove event?" for attendees. Responses 204, 409,
and 404 all result in successful removal from the local list.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-13 16:23:04 +01:00
parent 51ab99fc61
commit b067c0ef1e
12 changed files with 838 additions and 21 deletions

View File

@@ -0,0 +1,88 @@
# Feature Specification: Cancel Event from Event List
**Feature Branch**: `018-cancel-event-list`
**Created**: 2026-03-12
**Status**: Draft
**Input**: User description: "Wenn organisator das event auf der event listen seite löscht, kommt ein confirmation dialog mit einer warnung, dass das event abgesagt wird. Dann wird wirklich ein api call zum canceln des events gesendet"
## User Scenarios & Testing *(mandatory)*
### User Story 1 - Organizer Cancels Event from Event List (Priority: P1)
As an organizer viewing their event list, I want to cancel an event directly from the list so that I don't have to navigate into the event detail page first. When I tap the delete button on one of my events, a confirmation dialog warns me that the event will be permanently cancelled for all attendees. If I confirm, the system sends a cancellation request and removes the event from my list.
**Why this priority**: This is the core and only feature — enabling organizers to cancel events directly from the event list with clear warning about the irreversible consequence.
**Independent Test**: Can be fully tested by creating an event, navigating to the event list, tapping delete on the organizer's event, confirming in the dialog, and verifying the API call is made and the event is removed from the list.
**Acceptance Scenarios**:
1. **Given** an organizer is on the event list page and has an active (non-cancelled) event, **When** they tap the delete button on that event, **Then** a confirmation dialog appears with a warning that the event will be cancelled for all attendees.
2. **Given** the confirmation dialog is open, **When** the organizer confirms the cancellation, **Then** the system sends a cancel-event API request and, on success, removes the event from the local list.
3. **Given** the confirmation dialog is open, **When** the organizer taps the cancel button or presses Escape, **Then** the dialog closes and the event remains unchanged.
4. **Given** the organizer confirms cancellation, **When** the API call fails (network error, server error), **Then** the event is not removed from the list and an error message is shown.
---
### User Story 2 - Distinct Dialog for Organizer vs. Attendee Delete (Priority: P2)
The confirmation dialog must clearly differentiate between the organizer deleting (which cancels the event for everyone) and an attendee deleting (which only cancels their personal RSVP). The dialog text and warning level must reflect the severity of each action.
**Why this priority**: Prevents organizers from accidentally cancelling an event when they only intended to remove it from their view. The existing attendee delete flow already works — this story ensures the organizer flow has appropriate, distinct messaging.
**Independent Test**: Can be tested by comparing the dialog text when deleting as an organizer versus as an attendee for the same event, verifying the organizer dialog contains a stronger warning.
**Acceptance Scenarios**:
1. **Given** an organizer taps delete on their event, **When** the confirmation dialog appears, **Then** the title and message clearly state that the event will be cancelled permanently and all attendees will be affected.
2. **Given** an attendee taps delete on an event they RSVP'd to, **When** the confirmation dialog appears, **Then** the existing behavior is preserved — the message says their attendance will be cancelled and the event removed from their list.
---
### Edge Cases
- What happens when the organizer tries to cancel an event that is already cancelled? The frontend does not track cancelled status, so the delete button remains visible. If the API returns a 409 Conflict, the event is silently removed from the local list (since it is already cancelled server-side).
- What happens if the network request is in-flight and the user navigates away? The cancellation request should complete in the background; the local list update happens on next visit.
- What is the in-flight UI behavior during the cancellation API call? The existing ConfirmDialog pattern is used: no loading indicator, dialog remains open until API success (close + remove) or failure (stay open + show error). This is consistent with all other ConfirmDialog-based flows in the project.
- What happens when the organizer has both an organizer token and an RSVP for the same event? The organizer role takes precedence — the dialog shows the event-cancellation warning, not the RSVP-cancellation message.
## Clarifications
### Session 2026-03-12
- Q: How should already-cancelled events be handled in the list? → A: Frontend does not track cancelled status; delete button remains visible. On 409 Conflict, silently remove event from local list.
- Q: What is the in-flight UI behavior during the cancellation API call? → A: Use existing ConfirmDialog pattern — no loading indicator, dialog stays open until success or failure. Consistent with all other ConfirmDialog flows.
## Requirements *(mandatory)*
### Functional Requirements
- **FR-001**: When an organizer taps delete on their event in the event list, the system MUST show a confirmation dialog before taking any action.
- **FR-002**: The confirmation dialog for organizer events MUST clearly warn that the event will be cancelled permanently and that all attendees will be affected.
- **FR-003**: Upon confirmation, the system MUST send a cancel-event API request using the event's organizer token.
- **FR-004**: On successful cancellation (API returns success), the system MUST remove the event from the organizer's local event list.
- **FR-005**: On failed cancellation (network error or API error), the system MUST keep the event in the list and display an error message to the user. The confirmation dialog remains open.
- **FR-005a**: If the API returns 409 Conflict (event already cancelled), the system MUST silently remove the event from the local list (treated as success).
- **FR-006**: The confirmation dialog MUST provide a clear way to abort (cancel button, Escape key, overlay click) without triggering the cancellation.
- **FR-007**: The existing attendee and watcher delete flows MUST remain unchanged.
### Key Entities
- **Event**: Has an event token, organizer token (present only for the organizer), and cancelled status.
- **Confirmation Dialog**: Reusable UI component that displays a title, message, and confirm/cancel actions.
## Success Criteria *(mandatory)*
### Measurable Outcomes
- **SC-001**: Organizers can cancel an event from the event list in under 5 seconds (two taps: delete + confirm).
- **SC-002**: 100% of organizer cancellation attempts show the warning dialog before any API call is made.
- **SC-003**: After successful cancellation, the event disappears from the list immediately without requiring a page refresh.
- **SC-004**: Failed cancellation attempts preserve the event in the list and show a user-visible error message.
## Assumptions
- The cancel-event API endpoint (PATCH `/events/{eventToken}` with `cancelled: true`) already exists and is functional.
- The `ConfirmDialog` component already exists and can be reused with different title/message props.
- The `EventList` component already differentiates between organizer, attendee, and watcher roles using stored tokens.
- No cancellation reason is required when cancelling from the event list (unlike the event detail page, which offers an optional reason field). The list view prioritizes speed over detail.