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>
This commit is contained in:
57
specs/014-cancel-rsvp/quickstart.md
Normal file
57
specs/014-cancel-rsvp/quickstart.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# Quickstart: Cancel RSVP
|
||||
|
||||
**Feature**: 014-cancel-rsvp | **Date**: 2026-03-09
|
||||
|
||||
## Implementation Order
|
||||
|
||||
1. **OpenAPI spec** — Add DELETE endpoint to `api.yaml`
|
||||
2. **Regenerate types** — Backend (Maven generate) + Frontend (`npm run generate:api`)
|
||||
3. **Backend TDD** — Write tests → implement repository → service → controller
|
||||
4. **Frontend composable** — Add `removeRsvp()` to `useEventStorage.ts`
|
||||
5. **Frontend US-1** — RsvpBar tap-to-reveal + EventDetailView cancel logic
|
||||
6. **Frontend US-2** — EventList conditional dialog + server-side cancel before removal
|
||||
7. **Frontend US-3** — Edge case handling (stale tokens treated as success)
|
||||
8. **E2E tests** — Playwright tests for all three user stories
|
||||
|
||||
## Key Commands
|
||||
|
||||
```bash
|
||||
# Backend
|
||||
cd backend && ./mvnw test # Run backend tests
|
||||
cd backend && ./mvnw verify # Full verify (checkstyle + tests)
|
||||
cd backend && ./mvnw spring-boot:run # Run backend locally
|
||||
|
||||
# Frontend
|
||||
cd frontend && npm run generate:api # Regenerate types from OpenAPI
|
||||
cd frontend && npm run test:unit # Run unit tests
|
||||
cd frontend && npx playwright test # Run E2E tests
|
||||
cd frontend && npm run dev # Dev server
|
||||
|
||||
# Both
|
||||
cd backend && ./mvnw test && cd ../frontend && npm run test:unit # Quick check
|
||||
```
|
||||
|
||||
## Key Files to Modify
|
||||
|
||||
| File | Change |
|
||||
|------|--------|
|
||||
| `backend/src/main/resources/openapi/api.yaml` | Add DELETE `/events/{token}/rsvps/{rsvpToken}` |
|
||||
| `backend/.../port/in/CancelRsvpUseCase.java` | New use case interface |
|
||||
| `backend/.../port/out/RsvpRepository.java` | Add `deleteByEventIdAndRsvpToken()` |
|
||||
| `backend/.../RsvpJpaRepository.java` | Add derived delete query |
|
||||
| `backend/.../RsvpPersistenceAdapter.java` | Implement delete |
|
||||
| `backend/.../RsvpService.java` | Implement `CancelRsvpUseCase` |
|
||||
| `backend/.../EventController.java` | Add `cancelRsvp()` handler |
|
||||
| `frontend/src/composables/useEventStorage.ts` | Add `removeRsvp()` |
|
||||
| `frontend/src/components/RsvpBar.vue` | Tap-to-reveal cancel button |
|
||||
| `frontend/src/views/EventDetailView.vue` | Cancel logic + confirm dialog |
|
||||
| `frontend/src/components/EventList.vue` | Conditional dialog message + server cancel |
|
||||
| `frontend/e2e/cancel-rsvp.spec.ts` | E2E tests for all scenarios |
|
||||
|
||||
## Gotchas
|
||||
|
||||
- The JPA `deleteBy...` method requires `@Transactional` on the calling service method.
|
||||
- The `@Transactional` import must be `jakarta.transaction.Transactional` (not Spring's).
|
||||
- After updating OpenAPI spec, run `npm run generate:api` in frontend AND Maven generate-sources in backend.
|
||||
- The RsvpBar component currently has no click handler on the status state — this needs to be added carefully with proper accessibility (role, aria-expanded, keyboard support).
|
||||
- The EventList's `confirmDelete` currently calls `removeEvent()` synchronously — it needs to become async for the server call.
|
||||
Reference in New Issue
Block a user