E5-F4: Purchase Window Enforcement¶
Delivered by waiting-room (capacity mode)
This feature is implemented by the standalone waiting-room service in capacity mode: admitted tickets hold a session for session_ttl_seconds (e.g. 1200 = 20 min, matching the original spec). The ticketing backend (as the protected origin for checkout / seat selection) validates each request with GET /access; expired sessions return 410 → backend rejects with 401 → mobile client shows rejoin UI. The backend does not schedule its own window-expiry job — TTL is owned by waiting-room's BullMQ session-expire worker.
Epic: E5: Waiting Queue System
Size: S (Small)
Problem / Outcome¶
User has 20 minutes to complete purchase once at front of queue.
Scope¶
In-Scope:
- 20-minute window starts when user reaches front
- Cart TTL tied to purchase window
- Window expiration handling
Out-of-Scope:
- Window extension
Acceptance Criteria¶
- AC1: When user reaches front, 20-minute purchase window starts
- AC2: If window expires, user removed from queue and must rejoin at end
- AC3: Notification sent when window expires: "Your purchase window has expired"
Data Model Impact¶
QueueEntry table:
- window_started_at (TIMESTAMP, nullable)
- window_expires_at (TIMESTAMP, nullable)
- status (ENUM includes: window_expired)
Window expiration triggers:
- Release reserved seats
- Remove from active queue
- Send expiration notification
Permissions/Roles¶
- System
How to Verify¶
npm test -- --grep "purchase window"
Expected: Window enforced, expiration handled correctly.
Dependencies¶
Implementation Tasks¶
Doc References¶
Last Updated: January 2026