# Tasks: Cancel Event from Event List **Input**: Design documents from `/specs/018-cancel-event-list/` **Prerequisites**: plan.md, spec.md, research.md, data-model.md **Tests**: Mandatory per constitution (TDD — Red → Green → Refactor). **Organization**: Tasks are grouped by user story. No setup or foundational phases needed — all infrastructure exists. ## Format: `[ID] [P?] [Story] Description` - **[P]**: Can run in parallel (different files, no dependencies) - **[Story]**: Which user story this task belongs to (e.g., US1, US2) - Include exact file paths in descriptions --- ## Phase 1: User Story 1 — Organizer Cancels Event from List (Priority: P1) 🎯 MVP **Goal**: Organizers can cancel an event directly from the event list via confirmation dialog and PATCH API call. **Independent Test**: Create an event, navigate to event list, tap delete on organizer event, confirm in dialog, verify API call is made and event is removed from list. ### Tests for User Story 1 ⚠️ > **NOTE: Write these tests FIRST, ensure they FAIL before implementation** - [X] T001 [P] [US1] E2E test: organizer taps delete, confirms, event is removed after successful API call in `frontend/e2e/cancel-event-list.spec.ts` - [X] T002 [P] [US1] E2E test: organizer confirms cancellation, API fails, event stays in list and error message shown in `frontend/e2e/cancel-event-list.spec.ts` - [X] T003 [P] [US1] E2E test: organizer confirms cancellation, API returns 409 Conflict, event is silently removed from list in `frontend/e2e/cancel-event-list.spec.ts` - [X] T004 [P] [US1] E2E test: organizer opens cancel dialog then dismisses (cancel button, Escape, overlay click), event remains unchanged in `frontend/e2e/cancel-event-list.spec.ts` - [X] T005 [P] [US1] Unit test: `confirmDelete` calls PATCH cancel-event API when role is organizer in `frontend/src/components/__tests__/EventList.spec.ts` - [X] T006 [P] [US1] Unit test: `confirmDelete` treats 409 response as success (removes event from list) in `frontend/src/components/__tests__/EventList.spec.ts` ### Implementation for User Story 1 - [X] T007 [US1] Extend `confirmDelete` in `frontend/src/components/EventList.vue` to detect organizer role and call `api.PATCH('/events/{eventToken}')` with `{ cancelled: true }` and `organizerToken` query param - [X] T008 [US1] Handle 409 Conflict as success (silently remove event from local list) in `frontend/src/components/EventList.vue` - [X] T009 [US1] Handle API errors (keep dialog open, show error message) for organizer cancel in `frontend/src/components/EventList.vue` - [X] T010 [US1] Add organizer-specific dialog title ("Cancel event?") and message ("This will permanently cancel the event for all attendees.") in `frontend/src/components/EventList.vue` **Checkpoint**: Organizer can cancel events from the list. E2E and unit tests pass green. --- ## Phase 2: User Story 2 — Distinct Dialog for Organizer vs. Attendee (Priority: P2) **Goal**: Confirmation dialog clearly differentiates between organizer cancellation (severe, affects everyone) and attendee RSVP cancellation (personal). **Independent Test**: Compare dialog text when deleting as organizer vs. as attendee for the same event — organizer dialog must have stronger warning. ### Tests for User Story 2 ⚠️ > **NOTE: Write these tests FIRST, ensure they FAIL before implementation** - [X] T011 [P] [US2] E2E test: organizer dialog shows event-cancellation warning (title + message distinct from attendee) in `frontend/e2e/cancel-event-list.spec.ts` - [X] T012 [P] [US2] E2E test: attendee dialog preserves existing RSVP-cancellation message (no regression) in `frontend/e2e/cancel-event-list.spec.ts` - [X] T013 [P] [US2] Unit test: `deleteDialogMessage` and `deleteDialogTitle` return organizer-specific text when `getRole()` is organizer in `frontend/src/components/__tests__/EventList.spec.ts` - [X] T014 [P] [US2] Unit test: `deleteDialogMessage` returns existing attendee text unchanged when `getRole()` is attendee in `frontend/src/components/__tests__/EventList.spec.ts` ### Implementation for User Story 2 - [X] T015 [US2] Refactor `deleteDialogMessage` computed in `frontend/src/components/EventList.vue` to return role-differentiated text: organizer warning vs. existing attendee message - [X] T016 [US2] Add `deleteDialogTitle` computed in `frontend/src/components/EventList.vue` returning "Cancel event?" for organizer, "Remove event?" for attendee - [X] T017 [US2] Bind `deleteDialogTitle` to ConfirmDialog `:title` prop in `frontend/src/components/EventList.vue` **Checkpoint**: Dialog messages are clearly differentiated by role. All E2E and unit tests pass green. --- ## Phase 3: Polish & Cross-Cutting Concerns **Purpose**: Final validation and regression check - [X] T018 Run full frontend unit test suite (`npm run test:unit`) — verify no regressions - [X] T019 Run full E2E test suite (`npx playwright test`) — verify no regressions - [X] T020 Verify existing attendee and watcher delete flows unchanged (FR-007) via E2E tests --- ## Dependencies & Execution Order ### Phase Dependencies - **Phase 1 (US1)**: No dependencies — can start immediately (all infrastructure exists) - **Phase 2 (US2)**: Depends on Phase 1 completion (US2 refines the dialog created in US1) - **Phase 3 (Polish)**: Depends on Phase 1 + Phase 2 completion ### User Story Dependencies - **US1 (P1)**: Independent — core cancel flow + initial dialog message - **US2 (P2)**: Depends on US1 — refines dialog messaging created in US1 ### Within Each User Story - Tests MUST be written and FAIL before implementation (TDD) - Implementation tasks are sequential within each story (T007 → T008 → T009 → T010) - All test tasks within a story can run in parallel ### Parallel Opportunities - T001–T006 (US1 tests): All parallelizable — different test scenarios, same files but independent - T011–T014 (US2 tests): All parallelizable - US1 and US2 are sequential (US2 depends on US1) --- ## Parallel Example: User Story 1 ```bash # Launch all US1 tests in parallel (TDD — write first, expect red): Task: "E2E test: organizer cancels event successfully" (T001) Task: "E2E test: organizer cancel fails, error shown" (T002) Task: "E2E test: 409 Conflict handled as success" (T003) Task: "E2E test: dismiss dialog, event unchanged" (T004) Task: "Unit test: confirmDelete calls PATCH for organizer" (T005) Task: "Unit test: 409 treated as success" (T006) # Then implement sequentially: Task: "Extend confirmDelete for organizer role" (T007) Task: "Handle 409 Conflict" (T008) Task: "Handle API errors" (T009) Task: "Add organizer dialog title + message" (T010) ``` --- ## Implementation Strategy ### MVP First (User Story 1 Only) 1. Write US1 tests (T001–T006) — all should fail (red) 2. Implement US1 (T007–T010) — tests turn green 3. **STOP and VALIDATE**: Organizer can cancel events from list 4. Deploy/demo if ready ### Full Delivery 1. Complete US1 → MVP functional 2. Complete US2 → Dialog messaging polished 3. Complete Polish → Full regression validation --- ## Notes - No backend changes required — existing PATCH `/events/{eventToken}` endpoint used - No new components — ConfirmDialog reused as-is - No new dependencies - Primary change: ~50 lines in `EventList.vue` + tests