Files
nitrix 763811fce6
All checks were successful
CI / backend-test (push) Successful in 59s
CI / frontend-test (push) Successful in 23s
CI / frontend-e2e (push) Successful in 1m11s
CI / build-and-publish (push) Has been skipped
Add organizer-only attendee list to event detail view (011)
New GET /events/{token}/attendees endpoint returns attendee names when
a valid organizer token is provided (403 otherwise). The frontend
conditionally renders the list below the attendee count for organizers,
silently degrading for visitors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-08 18:34:27 +01:00

5.1 KiB

Implementation Plan: View Attendee List

Branch: 011-view-attendee-list | Date: 2026-03-08 | Spec: 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)

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)

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.