TC-EVT-009: Waitlist (Detailed)

Step-by-Step Guide — Follow each step exactly as written. All values are provided — do not improvise.
Module
Events & Registrations — Waitlist (#301–#308, #333–#335)
Staging Frontend
https://stg-rcme.membervu.com
Tenant
RCME
Test Users
Member + Guest + Anonymous + Events Manager
Priority
P1
What changed vs. the old guide: earlier pages said "there is no waitlist feature anywhere." That is now FALSE. Trust this page over any older TC-EVT-005 wording that hasn't been updated in the same pass.

Step 1: Create and fill a free event to capacity

StepActionExpected ResultTest Value
1Log in as the Events Manager.Dashboard loads.events@demo.membervu.com / Events123!
2Sidebar Events > Create Event (/admin/events/create).Create form opens.
3Fill a tiny-capacity FREE event.Fields populated.Name QA WL-009 Waitlist Test · Date today or future · Capacity 1 · Visibility PUBLIC · Registration RSVP · Price 0
4Save, then Publish.Event published, capacity 1.
5Log in as testmember → register for "QA WL-009 Waitlist Test".Status CONFIRMED; count 1/1 — event now full.testmember@rcme.membervu.com / Member123!

Step 2: Member, member+guest, and anonymous registrations all divert to waitlist (WL9-01/02/03)

StepActionExpected ResultTest Value
1Log out → log in as the Guest test account → open the event → Register.POST /api/events/:id/register returns success (not a capacity error). Registration status is WAITLISTED, not CONFIRMED.guest@demo.membervu.com / Guest123!
2Log out → log in as a different member (e.g. Treasurer test account) → register and add 1 guest at once, if the UI supports "bring a guest".Both the member's own registration AND the guest's registration are created with status WAITLISTED.treasurer@demo.membervu.com / Treasurer123! · Guest name WL Plus One
3Open a private browser window (no login) → go to the public event page (/rcme/events/<slug>) → register with a fresh email.Public registration (POST /api/public/rcme/events/:slug/register) also returns success with status WAITLISTED — same divert behavior as the authenticated path.Name Anon Waitlist QA · Email wl9.anon.qa@example.com

Step 3: Admin waitlist queue — FIFO order (WL9-04)

StepActionExpected ResultTest Value
1As Events Manager, open "QA WL-009 Waitlist Test" → Registration tab.WaitlistQueueSection renders a list titled Waitlist / Queue.
2Read the order of entries.Order matches join order from Step 2: Guest first, then Treasurer + plus-one, then the anonymous registrant last (GET /admin/events/:eventId/waitlist, createdAt asc).

Step 4: Approve with capacity override (WL9-05 / WL9-06)

StepActionExpected ResultTest Value
1With the event still full (1/1 confirmed), click Approve on the Guest's waitlisted entry WITHOUT any override option checked.POST /admin/events/:eventId/waitlist/:registrationId/approve with no override → 409 {"code":"WAITLIST_NO_SEATS"}. Entry remains WAITLISTED.
2Retry the same approval, this time checking/passing "Override capacity".200. The Guest's registration flips WAITLISTEDCONFIRMED; a ticket/check-in code is generated. Confirmed count is now 2/1 (deliberately over nominal capacity — expected, audit-logged as a warning, INV-4).
3Refresh the waitlist queue.The Guest's entry is gone from the waitlist; the Treasurer + plus-one and the anonymous registrant remain.

Step 5: Decline (WL9-07)

StepActionExpected ResultTest Value
1Click Decline on the anonymous registrant's waitlist entry.POST /admin/events/:eventId/waitlist/:registrationId/decline200. Status WAITLISTEDCANCELLED; entry disappears from the queue.
2Click Decline again on the SAME (now-cancelled) entry (or replay the request).200 no-op — {"message":"Already cancelled"}. Idempotent, NOT an error.

Step 6: Approving a non-WAITLISTED (e.g. CHECKED_IN) row is a safe no-op — NOT 409 (WL9-08)

Ground-truth correction: confirmed directly in adminWaitlistHandlers.ts and its test suite (approveWaitlistHandler.test.ts, cases A2/A4) — approving a registration whose status is no longer WAITLISTED (already approved, cancelled, or checked in) returns 200 {"alreadyApproved":true}, sends no second email, and is NOT an error. The only 409 on the approve endpoint is WAITLIST_NO_SEATS (Step 4.1). If your test plan or a teammate asserts a 409 here, that assertion is wrong — fix it against this page.
StepActionExpected ResultTest Value
1Take the Guest registration approved in Step 4.2 (now CONFIRMED) and check them in via the legacy check-in flow (TC-EVT-005 / POST /api/events/checkin) so status becomes CHECKED_IN.Registration status is now CHECKED_IN.
2Call Approve again on that same registrationId (e.g. replay the Step 4.2 approve request, or via API tool).200 {"alreadyApproved":true}. No error, no state change, no duplicate approval email sent.

Step 7: Approved-guest claim link (WL9-09) and no early setup email (WL9-10)

StepActionExpected ResultTest Value
1Right after the anonymous registrant (Step 2.3) joins the waitlist, check https://stg-webmail.membervu.com for that email address.No account-setup email arrives at join time — only whatever generic "you're on the waitlist" acknowledgment (if any) is sent, not the setup/claim email.Email wl9.anon.qa@example.com
2Create a second brand-new anonymous waitlist join (fresh event or same event after freeing another slot) with a never-before-seen email, then Approve it as admin.Approval succeeds; check webmail.Email wl9.claim.qa@example.com
3Open the approval email.Contains a claim link. Inspect the link's host.
4Verify the host and click the link.Host is the correct tenant origin (stg-rcme.membervu.com), not a broken/wrong domain. The link resolves and lets the guest set up / confirm their registration.

Step 8: Public "Join Waitlist" CTA — free events only (WL9-11)

StepActionExpected ResultTest Value
1Log out → open the public page for "QA WL-009 Waitlist Test" (a FREE event, still full).CTA reads "Join Waitlist" (not "Register", not "Sold Out" with no action) — driven by waitlistActive:true in the public event DTO.
2Create and publish a second event identical but PAID (Price > 0), fill it to capacity the same way, then view its public page logged out.CTA does NOT say "Join Waitlist" — the frontend gates the CTA on isFreeEvent even though the backend would accept a waitlist registration. Expect plain "Sold Out" / no actionable CTA.Name QA WL-009 Paid Waitlist Test · Price ₱500 · Capacity 1
Global kill-switch (informational, not directly testable on stage): waitlist can only be disabled tenant-wide via the backend env var WAITLIST_ENABLED='false' — there is no per-event toggle and no admin UI switch. Do not look for one.

CLEANUP