Add organizer cancel-event flow to EventList
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:
69
specs/018-cancel-event-list/plan.md
Normal file
69
specs/018-cancel-event-list/plan.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# Implementation Plan: Cancel Event from Event List
|
||||
|
||||
**Branch**: `018-cancel-event-list` | **Date**: 2026-03-12 | **Spec**: [spec.md](spec.md)
|
||||
**Input**: Feature specification from `/specs/018-cancel-event-list/spec.md`
|
||||
|
||||
## Summary
|
||||
|
||||
Enable organizers to cancel events directly from the event list page via the existing ConfirmDialog. The `EventList.vue` `confirmDelete` handler must detect the organizer role and call `PATCH /events/{eventToken}?organizerToken=...` with `{ cancelled: true }` instead of the existing RSVP deletion flow. The ConfirmDialog message must differentiate organizer cancellation (severe, affects all attendees) from attendee RSVP cancellation.
|
||||
|
||||
## Technical Context
|
||||
|
||||
**Language/Version**: TypeScript 5.x, Vue 3 (Composition API)
|
||||
**Primary Dependencies**: openapi-fetch, Vue Router, Vite
|
||||
**Storage**: localStorage via `useEventStorage()` composable
|
||||
**Testing**: Vitest (unit), Playwright + MSW (E2E)
|
||||
**Target Platform**: Mobile-first PWA (all modern browsers)
|
||||
**Project Type**: Web application (frontend-only change)
|
||||
**Performance Goals**: N/A (no new endpoints, minimal UI change)
|
||||
**Constraints**: No backend changes required; cancel-event API already exists
|
||||
**Scale/Scope**: ~50 lines of logic change in EventList.vue, dialog message updates
|
||||
|
||||
## Constitution Check
|
||||
|
||||
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
|
||||
|
||||
| Principle | Status | Notes |
|
||||
|-----------|--------|-------|
|
||||
| I. Privacy by Design | PASS | No new data collected or stored |
|
||||
| II. Test-Driven Methodology | PASS | Unit tests + E2E tests planned |
|
||||
| III. API-First Development | PASS | Uses existing PATCH endpoint already in OpenAPI spec |
|
||||
| IV. Simplicity & Quality | PASS | Extends existing delete flow, no new abstractions |
|
||||
| V. Dependency Discipline | PASS | No new dependencies |
|
||||
| VI. Accessibility | PASS | Reuses existing ConfirmDialog (already has aria-modal, alertdialog role, keyboard nav) |
|
||||
|
||||
All gates pass. No violations.
|
||||
|
||||
## Project Structure
|
||||
|
||||
### Documentation (this feature)
|
||||
|
||||
```text
|
||||
specs/018-cancel-event-list/
|
||||
├── plan.md # This file
|
||||
├── research.md # Phase 0 output
|
||||
├── data-model.md # Phase 1 output (minimal — no new entities)
|
||||
└── tasks.md # Phase 2 output (/speckit.tasks command)
|
||||
```
|
||||
|
||||
### Source Code (repository root)
|
||||
|
||||
```text
|
||||
frontend/src/
|
||||
├── components/
|
||||
│ ├── EventList.vue # PRIMARY CHANGE: confirmDelete handler + dialog message
|
||||
│ └── ConfirmDialog.vue # No changes needed
|
||||
├── api/
|
||||
│ ├── client.ts # No changes needed (openapi-fetch client)
|
||||
│ └── schema.d.ts # Already has PATCH /events/{eventToken} types
|
||||
└── composables/
|
||||
└── useEventStorage.ts # No changes needed
|
||||
|
||||
frontend/e2e/
|
||||
└── cancel-event-list.spec.ts # NEW: E2E tests for organizer cancellation
|
||||
|
||||
frontend/src/components/__tests__/
|
||||
└── EventList.spec.ts # EXTEND: Unit tests for organizer cancel flow
|
||||
```
|
||||
|
||||
**Structure Decision**: Frontend-only change. All logic changes in `EventList.vue`. No new components, composables, or API endpoints.
|
||||
Reference in New Issue
Block a user