Parent
#237
What to build
Implement the RSVP enrollment flow end-to-end: participant clicks "Confirm presence" → system creates enrollment with status confirmed → transition is recorded in audit trail → participant sees their enrollment in the App panel.
Action: EnrollUserAction
- Accepts event + user + enrollment method context
- For
rsvp and rsvp_checkin methods: creates enrollment with status confirmed (capacity validation comes in the next slice)
- Wraps in
DB::transaction
- Records transition in
events_enrollment_transitions (from_status=null, to_status=confirmed, triggered_by=user)
- Returns the created enrollment
Domain event (fire-and-forget, for future listeners):
- Dispatches
EnrollmentConfirmed implementing ShouldDispatchAfterCommit
- Payload: enrollment_id, event_id, user_id, xp_reward_rsvp (from policy)
- No listener in this slice — just the event dispatch
App panel (participant view):
- "My Events" page listing user's enrollments with status badges
- Event detail page with "Confirm Presence" button (visible when enrollment_method is rsvp or rsvp_checkin and user is not yet enrolled)
- Button dispatches EnrollUserAction
Admin panel (organizer view):
- Enrollments RelationManager on Event resource showing all enrollments with status, enrolled_at
- Read-only for now (management actions come in later slices)
Validation rules:
- User cannot enroll twice in same event (UNIQUE constraint)
- Event must be active and not past (
starts_at > now())
- Enrollment method must be
rsvp or rsvp_checkin (application flow is a separate slice)
Acceptance criteria
Blocked by
Parent
#237
What to build
Implement the RSVP enrollment flow end-to-end: participant clicks "Confirm presence" → system creates enrollment with status
confirmed→ transition is recorded in audit trail → participant sees their enrollment in the App panel.Action:
EnrollUserActionrsvpandrsvp_checkinmethods: creates enrollment with statusconfirmed(capacity validation comes in the next slice)DB::transactionevents_enrollment_transitions(from_status=null, to_status=confirmed, triggered_by=user)Domain event (fire-and-forget, for future listeners):
EnrollmentConfirmedimplementingShouldDispatchAfterCommitApp panel (participant view):
Admin panel (organizer view):
Validation rules:
starts_at > now())rsvporrsvp_checkin(application flow is a separate slice)Acceptance criteria
confirmedandenrolled_attimestampevents_enrollment_transitionsEnrollmentConfirmeddomain event is dispatched after transaction commitBlocked by