# Quickstart: RSVP to an Event (008)

## What this feature adds

1. **Backend**: New `POST /api/events/{eventToken}/rsvps` endpoint that accepts an RSVP (guest name) and returns an `rsvpToken`. Populates the existing `attendeeCount` field in `GET /events/{token}` with real data.

2. **Frontend**: Bottom sheet RSVP form on the event detail page. Sticky bottom bar with CTA (or status after RSVP). localStorage persistence of RSVP data.

## Implementation order

1. **Token value objects** — Create `EventToken`, `OrganizerToken`, `RsvpToken` records. Refactor `Event` domain model and all layers (service, controller, repository, persistence adapter, tests) to use typed tokens instead of raw UUID.
2. **OpenAPI spec** — Add `CreateRsvpRequest`, `CreateRsvpResponse`, and the `POST /events/{eventToken}/rsvps` endpoint.
3. **Liquibase migration** — Create `rsvps` table (003-create-rsvps-table.xml).
4. **Domain model** — `Rsvp` entity using `RsvpToken`.
5. **Ports** — `CreateRsvpUseCase` (in), `RsvpRepository` (out).
6. **Persistence adapter** — `RsvpJpaEntity`, `RsvpJpaRepository`, `RsvpPersistenceAdapter`.
7. **Service** — `RsvpService` implementing `CreateRsvpUseCase`.
8. **Controller** — Add `createRsvp()` to `EventController`.
9. **Attendee count** — Wire `RsvpRepository.countByEventId()` into the GET event flow.
10. **Frontend composable** — Extend `useEventStorage` with `rsvpToken`/`rsvpName`.
11. **Frontend UI** — Bottom sheet component, sticky bar, RSVP form.
12. **E2E tests** — RSVP submission, expired event guard, localStorage verification.

## Key files to touch

### Backend (new)
- `domain/model/EventToken.java`
- `domain/model/OrganizerToken.java`
- `domain/model/Rsvp.java`
- `domain/model/RsvpToken.java`
- `domain/port/in/CreateRsvpUseCase.java`
- `domain/port/out/RsvpRepository.java`
- `application/service/RsvpService.java`
- `adapter/out/persistence/RsvpJpaEntity.java`
- `adapter/out/persistence/RsvpJpaRepository.java`
- `adapter/out/persistence/RsvpPersistenceAdapter.java`
- `db/changelog/003-create-rsvps-table.xml`

### Backend (modified)
- `domain/model/Event.java` — UUID → EventToken/OrganizerToken
- `application/service/EventService.java` — use typed tokens
- `adapter/in/web/EventController.java` — typed tokens + wire attendee count + createRsvp()
- `adapter/in/web/GlobalExceptionHandler.java` — handle `EventExpiredException` (409)
- `adapter/out/persistence/EventPersistenceAdapter.java` — map typed tokens
- `domain/port/out/EventRepository.java` — typed token in signature
- `openapi/api.yaml` — new endpoint + schemas
- `db/changelog/db.changelog-master.xml` — include new migration
- All existing tests — update to use typed tokens

### Frontend (new)
- `src/components/BottomSheet.vue` — reusable bottom sheet
- `src/components/RsvpBar.vue` — sticky bottom bar (CTA or status)
- `e2e/event-rsvp.spec.ts` — E2E tests

### Frontend (modified)
- `src/views/EventDetailView.vue` — integrate RSVP bar + bottom sheet
- `src/composables/useEventStorage.ts` — add rsvpToken/rsvpName fields
- `src/api/schema.d.ts` — regenerated from OpenAPI
