# Tasks: View Attendee List **Input**: Design documents from `/specs/011-view-attendee-list/` **Prerequisites**: plan.md, spec.md, research.md, data-model.md, contracts/api.md **Tests**: Included — TDD enforced per constitution principle II. E2E tests mandatory per plan. **Organization**: Tasks grouped by user story for independent implementation and testing. ## 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) - Exact file paths included in all descriptions --- ## Phase 1: Setup (API Contract) **Purpose**: Define the API contract in OpenAPI and generate types for both backend and frontend. - [x] T001 Add `GET /events/{token}/attendees` endpoint, `GetAttendeesResponse`, and `Attendee` schemas to `backend/src/main/resources/openapi/api.yaml` per `contracts/api.md` - [x] T002 Regenerate backend Spring interfaces (`cd backend && ./mvnw compile`) - [x] T003 Regenerate frontend TypeScript types (`cd frontend && npm run generate:api`) **Checkpoint**: OpenAPI spec updated, generated types available in both backend and frontend. --- ## Phase 2: Foundational (Backend Domain Ports) **Purpose**: Create the inbound port and extend the outbound port that all backend implementation depends on. - [x] T004 [P] Create `GetAttendeesUseCase` inbound port interface in `backend/src/main/java/de/fete/domain/port/in/GetAttendeesUseCase.java` with method `List getAttendeeNames(UUID eventToken, UUID organizerToken)` - [x] T005 [P] Add `List findByEventId(Long eventId)` method to `backend/src/main/java/de/fete/domain/port/out/RsvpRepository.java` **Checkpoint**: Domain ports defined — service and adapter implementation can begin. --- ## Phase 3: User Story 1 — View Attendee List as Organizer (Priority: P1) 🎯 MVP **Goal**: Organizer sees a list of attendee names on the event detail page. Non-organizers see only the count (existing behavior). **Independent Test**: Create an event, submit RSVPs, then view the detail page with the organizer token. Attendee names should be listed. ### Tests for User Story 1 ⚠️ > **Write these tests FIRST — ensure they FAIL before implementation.** - [x] T006 [P] [US1] Write unit tests for `RsvpService.getAttendeeNames` (valid token, invalid token, event not found, no RSVPs) in `backend/src/test/java/de/fete/application/service/RsvpServiceTest.java` - [x] T007 [P] [US1] Write integration tests for `GET /events/{token}/attendees` (200 with attendees, 200 empty, 403 invalid token, 404 event not found) in `backend/src/test/java/de/fete/adapter/in/web/EventControllerIntegrationTest.java` - [x] T008 [P] [US1] Write unit tests for `AttendeeList.vue` (renders attendee names, empty state message, loading state) in `frontend/src/components/__tests__/AttendeeList.spec.ts` - [x] T009 [P] [US1] Write unit tests for organizer-conditional rendering in `EventDetailView.vue` (shows list for organizer, hides for visitor) in `frontend/src/views/__tests__/EventDetailView.spec.ts` - [x] T010 [P] [US1] Write E2E test: organizer sees attendee names, visitor sees count only, in `frontend/e2e/view-attendee-list.spec.ts` ### Backend Implementation for User Story 1 - [x] T011 [P] [US1] Add `findAllByEventIdOrderByIdAsc` query method to `backend/src/main/java/de/fete/adapter/out/persistence/RsvpJpaRepository.java` - [x] T012 [P] [US1] Implement `findByEventId` in `backend/src/main/java/de/fete/adapter/out/persistence/RsvpPersistenceAdapter.java` - [x] T013 [US1] Implement `GetAttendeesUseCase` in `backend/src/main/java/de/fete/application/service/RsvpService.java` — look up event by token, verify organizer token, return attendee names ordered by ID - [x] T014 [US1] Add `getAttendees` endpoint handler to `backend/src/main/java/de/fete/adapter/in/web/EventController.java` — map to `GetAttendeesUseCase`, return 200/403/404 ### Frontend Implementation for User Story 1 - [x] T015 [US1] Create `AttendeeList.vue` component in `frontend/src/components/AttendeeList.vue` — accepts attendee names array as prop, renders semantic `