Add RSVP feature: submit RSVP, block on expired events #16

Merged
nitrix merged 8 commits from 008-rsvp into master 2026-03-08 13:39:36 +01:00
Owner

Summary

  • Typed token value objects (EventToken, OrganizerToken, RsvpToken) with full codebase refactoring
  • RSVP creation endpoint (POST /events/{token}/rsvps) with attendee count
  • Bottom sheet RSVP form with localStorage persistence and organizer exclusion
  • Expired event blocking: 409 Conflict server-side, hidden RSVP bar client-side
  • expiryDate > eventDate validation with ExpiryDateBeforeEventException
  • Injected Clock in RsvpService and EventService for deterministic tests
  • ArchUnit rule: web adapter must not depend on outbound ports
  • DB count assertions on all rejection integration tests

Test plan

  • 55 backend tests (unit + integration + ArchUnit)
  • 51 frontend unit tests (BottomSheet, RsvpBar, useEventStorage, EventDetailView)
  • 19 E2E tests (Playwright with MSW mocks)
  • mvnw verify green (SpotBugs 0, Checkstyle 0)
  • npm run build green (type-check + Vite)
  • Visual verification via browser-interactive-testing

🤖 Generated with Claude Code

## Summary - Typed token value objects (`EventToken`, `OrganizerToken`, `RsvpToken`) with full codebase refactoring - RSVP creation endpoint (`POST /events/{token}/rsvps`) with attendee count - Bottom sheet RSVP form with localStorage persistence and organizer exclusion - Expired event blocking: 409 Conflict server-side, hidden RSVP bar client-side - `expiryDate > eventDate` validation with `ExpiryDateBeforeEventException` - Injected `Clock` in `RsvpService` and `EventService` for deterministic tests - ArchUnit rule: web adapter must not depend on outbound ports - DB count assertions on all rejection integration tests ## Test plan - [x] 55 backend tests (unit + integration + ArchUnit) - [x] 51 frontend unit tests (BottomSheet, RsvpBar, useEventStorage, EventDetailView) - [x] 19 E2E tests (Playwright with MSW mocks) - [x] `mvnw verify` green (SpotBugs 0, Checkstyle 0) - [x] `npm run build` green (type-check + Vite) - [x] Visual verification via browser-interactive-testing 🤖 Generated with [Claude Code](https://claude.com/claude-code)
nitrix added 8 commits 2026-03-08 13:36:47 +01:00
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>
Introduce typed token value objects (EventToken, OrganizerToken,
RsvpToken) and refactor all existing Event code to use them.

Add POST /events/{token}/rsvps endpoint that persists an RSVP and
returns an rsvpToken. Populate attendeeCount in GET /events/{token}
from a real count query instead of hardcoded 0.

Includes: OpenAPI spec, Liquibase migration (rsvps table with
ON DELETE CASCADE), domain model, hexagonal ports/adapters,
service layer, and full test coverage (unit + integration).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The EventController was directly accessing RsvpRepository (an outbound port)
to count attendees, bypassing the application layer. Introduce a dedicated
inbound port and implement it in RsvpService. Remove the now-unused Clock
dependency from RsvpService.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevents future regressions where controllers bypass the application layer
and access repositories directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Introduces BottomSheet and RsvpBar components, integrates the RSVP
submission flow into EventDetailView, extends useEventStorage with
saveRsvp/getRsvp, and adds unit tests plus an E2E spec for the RSVP
workflow.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds expiry check to RsvpService using an injected Clock for testability,
handles EventExpiredException in GlobalExceptionHandler as 409 Conflict,
and adds unit + integration tests using relative dates from a fixed clock.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Validate expiryDate is strictly after eventDate and harden rejection tests
All checks were successful
CI / backend-test (push) Successful in 59s
CI / frontend-test (push) Successful in 22s
CI / frontend-e2e (push) Successful in 56s
CI / build-and-publish (push) Has been skipped
90bfd12bf3
Adds ExpiryDateBeforeEventException (400) when expiryDate <= eventDate,
asserts DB row count unchanged after every rejection in integration tests,
and replaces all hardcoded dates in EventServiceTest with TODAY-relative
expressions derived from the fixed Clock.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
nitrix merged commit 2da36058ae into master 2026-03-08 13:39:36 +01:00
nitrix deleted branch 008-rsvp 2026-03-08 13:39:36 +01:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: nitrix/fete#16