Parent
#237
What to build
Add atomic capacity checking to the enrollment flow. When an event is full, participants are placed on a waitlist (FIFO) if the policy allows, otherwise enrollment is rejected.
Modify EnrollUserAction:
- Inside
DB::transaction, use lockForUpdate() on the enrollment policy to prevent race conditions
- Count current
confirmed + checked_in + attended enrollments for the event
- If count < capacity (or capacity is null/unlimited): confirm as before
- If count >= capacity AND
has_waitlist = true: create enrollment with status waitlisted, assign waitlist_position (max position + 1)
- If count >= capacity AND
has_waitlist = false: throw validation exception (422 "Event is full")
- Record appropriate transition in audit trail
Domain event:
- Dispatch
EnrollmentWaitlisted (for future notifications) implementing ShouldDispatchAfterCommit
Admin panel:
- Waitlist column visible in enrollments RelationManager
- Filter enrollments by status (confirmed, waitlisted, etc.)
App panel:
- Show "You are on the waitlist (position X)" when status is
waitlisted
- Show "Event is full" message when capacity reached and no waitlist
Scopes on EventEnrollment model:
scopeConfirmed(), scopeWaitlisted(), scopeActive() (confirmed + checked_in + attended)
Acceptance criteria
Blocked by
Parent
#237
What to build
Add atomic capacity checking to the enrollment flow. When an event is full, participants are placed on a waitlist (FIFO) if the policy allows, otherwise enrollment is rejected.
Modify
EnrollUserAction:DB::transaction, uselockForUpdate()on the enrollment policy to prevent race conditionsconfirmed + checked_in + attendedenrollments for the eventhas_waitlist = true: create enrollment with statuswaitlisted, assignwaitlist_position(max position + 1)has_waitlist = false: throw validation exception (422 "Event is full")Domain event:
EnrollmentWaitlisted(for future notifications) implementingShouldDispatchAfterCommitAdmin panel:
App panel:
waitlistedScopes on EventEnrollment model:
scopeConfirmed(),scopeWaitlisted(),scopeActive()(confirmed + checked_in + attended)Acceptance criteria
waitlist_position(FIFO)lockForUpdate()is used inside transaction for atomicityBlocked by