# Implementation Plan: View Attendee List

**Branch**: `011-view-attendee-list` | **Date**: 2026-03-08 | **Spec**: [spec.md](spec.md)
**Input**: Feature specification from `/specs/011-view-attendee-list/spec.md`

## Summary

Add an organizer-only attendee list to the event detail view. A new `GET /events/{token}/attendees?organizerToken=<uuid>` endpoint returns attendee names when the organizer token is valid (403 otherwise). The frontend conditionally renders the list below the attendee count when the viewer is identified as the organizer via localStorage.

## Technical Context

**Language/Version**: Java 25 (backend), TypeScript 5.9 (frontend)
**Primary Dependencies**: Spring Boot 3.5.x, Vue 3, Vue Router 5, openapi-fetch, openapi-typescript
**Storage**: PostgreSQL (JPA via Spring Data, Liquibase migrations)
**Testing**: JUnit + Testcontainers (backend integration), Vitest (frontend unit), Playwright + MSW (E2E)
**Target Platform**: Self-hosted web application (PWA)
**Project Type**: Web application (full-stack)
**Performance Goals**: Attendee list loads within 2 seconds (SC-001)
**Constraints**: Privacy by Design — attendee names only exposed to organizer; no PII logging
**Scale/Scope**: Small-to-medium events; no pagination required (spec assumption)

## Constitution Check

*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*

| Principle | Status | Notes |
|-----------|--------|-------|
| I. Privacy by Design | ✅ PASS | Attendee names only exposed via organizer token verification. Non-organizers see count only (FR-003). No analytics/tracking added. |
| II. Test-Driven Methodology | ✅ PASS | Plan follows Research → Spec → Test → Implement. TDD enforced. E2E tests mandatory for both user stories. |
| III. API-First Development | ✅ PASS | New endpoint defined in OpenAPI spec first. Types generated before implementation. Response schemas include `example:` fields. |
| IV. Simplicity & Quality | ✅ PASS | Minimal new code: one endpoint, one use case, one component section. No over-engineering. |
| V. Dependency Discipline | ✅ PASS | No new dependencies introduced. |
| VI. Accessibility | ✅ PASS | Semantic HTML list for attendees. WCAG AA contrast. Keyboard-navigable. |

**Gate result**: ALL PASS — proceed to Phase 0.

## Project Structure

### Documentation (this feature)

```text
specs/011-view-attendee-list/
├── plan.md              # This file
├── research.md          # Phase 0 output
├── data-model.md        # Phase 1 output
├── contracts/           # Phase 1 output
│   └── api.md           # New endpoint contract
└── tasks.md             # Phase 2 output (/speckit.tasks)
```

### Source Code (repository root)

```text
backend/
├── src/main/java/de/fete/
│   ├── domain/
│   │   ├── model/                          # Existing: Event, Rsvp, tokens
│   │   └── port/
│   │       ├── in/
│   │       │   └── GetAttendeesUseCase.java    # NEW: inbound port
│   │       └── out/
│   │           └── RsvpRepository.java         # MODIFY: add findByEventId
│   ├── application/service/
│   │   └── RsvpService.java                    # MODIFY: implement GetAttendeesUseCase
│   ├── adapter/
│   │   ├── in/web/
│   │   │   └── EventController.java            # MODIFY: add attendees endpoint
│   │   └── out/persistence/
│   │       ├── RsvpJpaRepository.java          # MODIFY: add findByEventId query
│   │       └── RsvpPersistenceAdapter.java     # MODIFY: implement findByEventId
│   └── src/main/resources/openapi/
│       └── api.yaml                            # MODIFY: add attendees endpoint + schema
├── src/test/java/de/fete/
│   ├── adapter/in/web/
│   │   └── EventControllerIntegrationTest.java # MODIFY: add attendees tests
│   └── application/service/
│       └── RsvpServiceTest.java                # MODIFY: add getAttendees tests

frontend/
├── src/
│   ├── views/
│   │   └── EventDetailView.vue                 # MODIFY: add attendee list section
│   ├── components/
│   │   └── AttendeeList.vue                    # NEW: attendee list component
│   ├── api/
│   │   └── schema.d.ts                         # REGENERATED from OpenAPI
│   └── composables/
│       └── useEventStorage.ts                  # NO CHANGES (read-only usage)
├── src/views/__tests__/
│   └── EventDetailView.spec.ts                 # MODIFY: add attendee list tests
├── src/components/__tests__/
│   └── AttendeeList.spec.ts                    # NEW: unit tests
└── e2e/
    └── view-attendee-list.spec.ts              # NEW: E2E tests
```

**Structure Decision**: Extends the existing web application structure. Backend follows hexagonal architecture with new inbound port + implementation. Frontend adds one new component integrated into the existing EventDetailView.

## Complexity Tracking

> No constitution violations — section not applicable.
