Happy path
Staff taps Walk-Ins tab.
Tab visible only when at least one access type allows walk-ins (per access-type config flag). Otherwise, hidden.
Quick-add form.
Three fields: name (required), email (optional), access type (required if >1 walk-in-allowed type). Email omitted? No confirmation email sent — they get a printed/verbal handoff.
Submit creates registration + check-in atomically.
Single endpoint POST that creates registration, marks confirmed, AND records a check-in event. Idempotency-key per form session. Server returns the new guest_id + display name for confirmation.
Confirmation: "Added & checked in" + return to form.
Auto-clears form after 1.5s for the next walk-in. Pending-sync banner increments if offline.
Failure modes
Walk-ins not allowed for any access type
Trigger: event has all access types with allow_walkins=false.
Walk-Ins tab is hidden entirely. Staff who need to add must contact organizer for config change. Harness: stub event without walk-in-allowed types, tab not visible.
Capacity-full mid-form
Trigger: staff opens form, types name; before submit, last seat goes to another walk-in.
Submit returns 409 SOLD_OUT with banner "Sold out — but you can add to waitlist." Form preserves the typed name + offers waitlist conversion. Harness: stub capacity claim during form-fill, submit, banner visible.
Duplicate-email collision
Trigger: staff enters an email that already has a confirmed registration for this event.
Server returns 409 ALREADY_REGISTERED with "[Name] is already registered. Check in instead?" link to the existing record. Harness: stub existing reg, submit, ALREADY_REGISTERED visible.
Empty-email walk-in
Trigger: staff omits email entirely (paper-attendee scenario).
Allowed. Server stores email=null on the registration. No confirmation email. Audit log row notes "walk-in without email." If two walk-ins later have same name, they're separate registrations — name is not a unique key. Harness: submit with empty email, registration created, no email enqueued.
Offline walk-in
Trigger: device is offline; staff submits walk-in.
Inherits native-app-shell offline contract. Walk-in row created locally with idempotency-key, queued for sync. Confirmation says "Added & queued — will sync when online." Harness: device-state=offline, submit, local row visible, pending-sync banner increments.
Two-staff race on same email
Trigger: two staff both walk-in the same email simultaneously.
Server-side uniqueness on (event_id, email) for confirmed registrations resolves the race — second submit returns 409 ALREADY_REGISTERED. Harness: 2 devices submit same email within 100ms, exactly one 200, one 409.
Permission gate
Trigger: check-in-staff role tries to walk-in (might not have add-guest ability).
Walk-in requires walkins:add ability. Roles that lack it see hidden Walk-Ins tab. Harness: check-in-staff without walkins:add, tab hidden, server POST returns 403.
Audit row creates both registration + check-in
Trigger: walk-in succeeds.
Audit log gets two rows: registration_created + check_in, both timestamped, same actor + same scan_ts. Harness: walk-in submit, server audit log has both rows.
Auto-clear timer interrupted by next-tap
Trigger: staff taps "Add another" before the 1.5s auto-clear timer.
Tap cancels the timer immediately, clears the form, refocuses name input. No flicker. Harness: simulate rapid tap, no double-render.
Cross-tenant walk-in attempt
Trigger: forged event_id in walk-in submit (tenant attempting cross-tenant write).
Server returns 404. Harness: forge event_id, submit, server 404.
Stable test attributes
walkin-tab | Tab nav | Visible only when access types allow walk-ins |
walkin-form | Tab content | Quick-add form |
walkin-name-input | Form | Required field |
walkin-email-input | Form | Optional field |
walkin-access-type-picker | Form | Required if >1 walk-in-allowed type |
walkin-submit | Form | Creates registration + check-in atomically |
walkin-confirmation | Post-submit | "Added & checked in" |
walkin-sold-out-banner | 409 SOLD_OUT | + waitlist conversion offer |
walkin-already-registered | 409 ALREADY_REGISTERED | + "check in instead" link |
Agent test plan
Probe list
- (manual) walkin-tab-hidden-when-disabled: stub event without walkin-allowed types, tab not visible
- (manual) capacity-full-mid-form: 409 SOLD_OUT + waitlist offer
- (manual) duplicate-email-409: existing reg, ALREADY_REGISTERED with check-in link
- (manual) empty-email-allowed: submit without email, registration created no email enqueued
- (manual) offline-walkin-queues: device offline, local row created, pending banner increments
- (manual) two-staff-race-resolved: 2 devices same email, exactly one 200
- (manual) permission-gate: role without walkins:add, tab hidden + 403
- audit-log-both-rows: walk-in success, registration_created + check_in audit rows
- (manual) auto-clear-cancellable: rapid tap, no flicker
- cross-tenant-404: forged event_id, 404