Files
fete/specs/008-rsvp/tasks.md
nitrix 4828d06aba Add 008-rsvp feature spec and design artifacts
Spec, research decisions, implementation plan, data model,
API contract, and task breakdown for the RSVP feature.

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

11 KiB

Tasks: RSVP to an Event

Input: Design documents from /specs/008-rsvp/ Prerequisites: plan.md, spec.md, data-model.md, contracts/create-rsvp.yaml, research.md, quickstart.md

Tests: Included — constitution mandates Test-Driven Methodology (tests before implementation).

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 descriptions

Phase 1: Setup

Purpose: OpenAPI spec and database migration — shared infrastructure for all user stories

  • T001 Update OpenAPI spec with RSVP endpoint, request/response schemas, and attendeeCount population in backend/src/main/resources/openapi/api.yaml
  • T002 [P] Create Liquibase migration for rsvps table in backend/src/main/resources/db/changelog/003-create-rsvps-table.xml
  • T003 [P] Include new migration in backend/src/main/resources/db/changelog/db.changelog-master.xml

Phase 2: Foundational (Blocking Prerequisites)

Purpose: Token value objects and cross-cutting refactoring — MUST complete before user stories

Why blocking: All new RSVP code uses typed tokens. Existing code must be refactored first to avoid mixing raw UUID and typed tokens.

  • T004 [P] Create EventToken record in backend/src/main/java/de/fete/domain/model/EventToken.java
  • T005 [P] Create OrganizerToken record in backend/src/main/java/de/fete/domain/model/OrganizerToken.java
  • T006 [P] Create RsvpToken record in backend/src/main/java/de/fete/domain/model/RsvpToken.java
  • T007 Refactor Event domain model to use EventToken/OrganizerToken in backend/src/main/java/de/fete/domain/model/Event.java
  • T008 Refactor EventRepository port to use typed tokens in backend/src/main/java/de/fete/domain/port/out/EventRepository.java
  • T009 Refactor EventPersistenceAdapter to map typed tokens in backend/src/main/java/de/fete/adapter/out/persistence/EventPersistenceAdapter.java
  • T010 Refactor EventService to use typed tokens in backend/src/main/java/de/fete/application/service/EventService.java
  • T011 Refactor EventController to unwrap/wrap typed tokens at API boundary in backend/src/main/java/de/fete/adapter/in/web/EventController.java
  • T012 Update EventServiceTest to use typed tokens in backend/src/test/java/de/fete/application/service/EventServiceTest.java
  • T013 Update EventControllerIntegrationTest to use typed tokens in backend/src/test/java/de/fete/adapter/in/web/EventControllerIntegrationTest.java
  • T014 Verify all existing tests pass after token refactoring (cd backend && ./mvnw test)

Checkpoint: All existing tests green with typed tokens. New RSVP domain work can begin.


Phase 3: User Story 1 — Submit an RSVP (Priority: P1) MVP

Goal: A guest can open an active event page, tap the RSVP CTA, enter their name, submit, and see confirmation. Server persists the RSVP and returns an rsvpToken. localStorage stores RSVP data. Attendee count is populated from real data.

Independent Test: Open an event page, submit an RSVP with a name, verify attendee count updates, verify localStorage contains rsvpToken and name.

Backend Tests for US1

  • T015 [P] [US1] Write unit tests for RsvpService (create RSVP, validation, event-not-found) in backend/src/test/java/de/fete/application/service/RsvpServiceTest.java
  • T016 [P] [US1] Write integration tests for POST /events/{eventToken}/rsvps (201 success, 400 validation, 404 not found) in backend/src/test/java/de/fete/adapter/in/web/EventControllerIntegrationTest.java

Backend Implementation for US1

  • T017 [P] [US1] Create Rsvp domain entity in backend/src/main/java/de/fete/domain/model/Rsvp.java
  • T018 [P] [US1] Create CreateRsvpUseCase inbound port in backend/src/main/java/de/fete/domain/port/in/CreateRsvpUseCase.java
  • T019 [P] [US1] Create RsvpRepository outbound port with save() and countByEventId() in backend/src/main/java/de/fete/domain/port/out/RsvpRepository.java
  • T020 [P] [US1] Create RsvpJpaEntity in backend/src/main/java/de/fete/adapter/out/persistence/RsvpJpaEntity.java
  • T021 [P] [US1] Create RsvpJpaRepository (Spring Data) in backend/src/main/java/de/fete/adapter/out/persistence/RsvpJpaRepository.java
  • T022 [US1] Implement RsvpPersistenceAdapter in backend/src/main/java/de/fete/adapter/out/persistence/RsvpPersistenceAdapter.java
  • T023 [US1] Implement RsvpService (create RSVP logic, validate event exists) in backend/src/main/java/de/fete/application/service/RsvpService.java
  • T024 [US1] Add createRsvp() method to EventController in backend/src/main/java/de/fete/adapter/in/web/EventController.java
  • T025 [US1] Wire attendee count: add countByEventId() call to GET event flow, populate attendeeCount in response in backend/src/main/java/de/fete/adapter/in/web/EventController.java
  • T026 [US1] Verify backend tests pass (cd backend && ./mvnw test)

Frontend Tests for US1

  • T027 [P] [US1] Write unit tests for BottomSheet component in frontend/src/components/__tests__/BottomSheet.spec.ts
  • T028 [P] [US1] Write unit tests for RsvpBar component in frontend/src/components/__tests__/RsvpBar.spec.ts
  • T029 [P] [US1] Update unit tests for useEventStorage composable (rsvpToken/rsvpName fields) in frontend/src/composables/__tests__/useEventStorage.spec.ts

Frontend Implementation for US1

  • T030 [US1] Regenerate TypeScript types from updated OpenAPI spec (frontend/src/api/schema.d.ts)
  • T031 [P] [US1] Extend useEventStorage composable with rsvpToken and rsvpName fields in frontend/src/composables/useEventStorage.ts
  • T032 [P] [US1] Create BottomSheet.vue component (slide-up, backdrop, focus trap, ESC close, aria-modal) in frontend/src/components/BottomSheet.vue
  • T033 [P] [US1] Create RsvpBar.vue sticky bottom bar (CTA state + status state) in frontend/src/components/RsvpBar.vue
  • T034 [US1] Integrate RsvpBar + BottomSheet + RSVP form into EventDetailView, including error state when server is unreachable, in frontend/src/views/EventDetailView.vue
  • T035 [US1] Add bottom sheet and sticky bar styles to frontend/src/assets/main.css
  • T036 [US1] Update EventDetailView unit tests for RSVP integration in frontend/src/views/__tests__/EventDetailView.spec.ts

E2E Tests for US1

  • T037 [US1] Write E2E tests: RSVP submission flow, localStorage verification, attendee count update in frontend/e2e/event-rsvp.spec.ts

Checkpoint: US1 complete — guest can submit RSVP, see confirmation, attendee count populated. All backend + frontend tests green.


Phase 4: User Story 2 — RSVP Blocked on Expired Events (Priority: P2)

Goal: Expired events hide the RSVP form and the server rejects RSVP submissions with 409 Conflict.

Independent Test: Attempt to RSVP to an expired event — verify form is hidden client-side and server returns 409.

Tests for US2

  • T038 [P] [US2] Write backend test for expired event rejection (409) in backend/src/test/java/de/fete/application/service/RsvpServiceTest.java
  • T039 [P] [US2] Write integration test for POST /events/{eventToken}/rsvps returning 409 on expired event in backend/src/test/java/de/fete/adapter/in/web/EventControllerIntegrationTest.java

Implementation for US2

  • T040 [US2] Add expiry check to RsvpService.createRsvp() — throw EventExpiredException when event date has passed in backend/src/main/java/de/fete/application/service/RsvpService.java
  • T041 [US2] Handle EventExpiredException in GlobalExceptionHandler — return 409 Conflict in backend/src/main/java/de/fete/adapter/in/web/GlobalExceptionHandler.java
  • T042 [US2] Hide RSVP bar/form on expired events in EventDetailView (check expired field from API response) in frontend/src/views/EventDetailView.vue
  • T043 [US2] Write E2E test for expired event: verify RSVP form hidden, direct API call returns 409 in frontend/e2e/event-rsvp.spec.ts
  • T044 [US2] Verify all tests pass (cd backend && ./mvnw test && cd ../frontend && npm run test:unit)

Checkpoint: US2 complete — expired events block RSVPs client-side and server-side.


Phase 5: Polish & Cross-Cutting Concerns

Purpose: Final verification across all stories

  • T045 Run full backend verify (cd backend && ./mvnw verify)
  • T046 Run frontend build and type-check (cd frontend && npm run build)
  • T047 Run all E2E tests (cd frontend && npx playwright test)
  • T048 Visual verification of RSVP flow using browser-interactive-testing skill

Dependencies & Execution Order

Phase Dependencies

  • Setup (Phase 1): No dependencies — can start immediately
  • Foundational (Phase 2): Depends on T001 (OpenAPI spec) for schema awareness; T002-T003 (migration) independent
  • US1 (Phase 3): Depends on Phase 2 completion (typed tokens in place)
  • US2 (Phase 4): Depends on Phase 3 (RSVP creation must exist before expiry guard)
  • Polish (Phase 5): Depends on all user stories complete

User Story Dependencies

  • US1 (P1): Can start after Phase 2 — no dependency on US2
  • US2 (P2): Depends on US1 (the RSVP endpoint and form must exist before adding the expiry guard)

Within Each User Story

  • Tests MUST be written first and FAIL before implementation
  • Domain model/ports before persistence adapters
  • Persistence before services
  • Services before controllers
  • Backend before frontend (API must exist for frontend to consume)
  • Frontend components before view integration
  • Unit tests before E2E tests

Parallel Opportunities

Phase 1: T002 and T003 can run in parallel with T001 Phase 2: T004, T005, T006 in parallel; then T007-T013 sequentially (refactoring chain) Phase 3 Backend: T015+T016 (tests) in parallel; T017+T018+T019+T020+T021 (domain/ports/JPA) in parallel; then T022→T023→T024→T025 sequential Phase 3 Frontend: T027+T028+T029 (tests) in parallel; T031+T032+T033 in parallel; then T034→T035→T036→T037 sequential Phase 4: T038+T039 (tests) in parallel; then T040→T041→T042→T043→T044 sequential


Implementation Strategy

MVP First (User Story 1 Only)

  1. Complete Phase 1: Setup (OpenAPI + migration)
  2. Complete Phase 2: Foundational (token value objects + refactoring)
  3. Complete Phase 3: User Story 1 (full RSVP flow)
  4. STOP and VALIDATE: Guest can submit RSVP, see confirmation, attendee count works
  5. Deploy/demo if ready

Incremental Delivery

  1. Setup + Foundational → Token refactoring complete, schema ready
  2. Add US1 → Full RSVP flow works → Deploy/Demo (MVP!)
  3. Add US2 → Expired events guarded → Deploy/Demo
  4. Polish → All tests green, visual verification done

Notes

  • Cancelled event guard (FR-010) is deferred until US-18 — NOT included in tasks
  • No CAPTCHA/rate-limiting per spec (KISS, privacy-first)
  • RSVP editing/withdrawal deferred to separate edit-RSVP spec
  • Frontend uses plain string for tokens (no branded types) per clarification
  • Backend uses typed records (EventToken, OrganizerToken, RsvpToken) per clarification