6.4 KiB
Booking Flow
This document describes the full public booking, confirmation, QR generation, and entrance check-in flow.
1. Public Discovery
- A visitor opens the public website.
- The Angular frontend requests published shows and upcoming performances from the backend.
- The visitor opens a show detail page.
- The frontend displays upcoming public performances and availability returned by the backend.
Availability shown to visitors is informational. The backend recalculates availability when reservation state changes.
2. Booking Submission
- The visitor selects a performance.
- The frontend displays the booking form for that performance.
- The visitor enters contact details and party size.
- The frontend submits the booking request to the backend.
- The backend validates:
- required fields;
- email format;
- positive party size;
- performance exists and booking is open;
- requested seats do not exceed currently available seats.
- The backend creates a
pendingreservation. - The backend creates a random opaque confirmation token.
- After the transaction commits successfully, the backend sends an email with a confirmation link.
- The frontend tells the visitor to check their email.
The reservation is not confirmed at this stage.
3. Email Confirmation
- The visitor opens the confirmation link from the email.
- The frontend or backend submits the confirmation token to the confirmation endpoint.
- The backend validates that the token:
- exists;
- has the
confirmationpurpose; - belongs to a pending reservation;
- has not expired;
- has not already been used.
- The backend starts a database transaction.
- The backend locks the related performance row.
- The backend recalculates confirmed reservations for the performance.
- The backend confirms the reservation only if enough seats remain.
- The backend marks the confirmation token as used.
- The backend creates a separate
check_intoken for QR verification. - The backend generates a QR code containing only the opaque check-in token or a verification URL built from that token.
- The backend returns or sends the QR code to the visitor.
If there is no longer enough capacity, the backend must not confirm the reservation.
4. QR Code Delivery
After confirmation, the visitor receives access to a QR code.
The QR code may be delivered as:
- an image displayed on the confirmation page;
- an image or link in a confirmation email;
- a printable page linked from the confirmation result.
The QR code must be usable from a smartphone screen or printed copy.
The QR code must contain:
- an opaque check-in token; or
- a verification URL containing an opaque token.
The QR code must not contain:
- visitor name;
- email address;
- phone number;
- notes;
- party size if avoidable;
- any other personal data.
5. Entrance Check-In
- Staff signs in with an account that has check-in permission.
- Staff opens a mobile-friendly web page for entrance check-in.
- Staff scans the visitor's QR code with the device camera or enters the QR token manually.
- The QR code provides only an opaque check-in token or verification URL.
- The frontend submits the token to the backend for a verification preview.
- The backend validates:
- staff authentication and permission;
- token exists and has the
check_inpurpose; - reservation exists;
- reservation is confirmed;
- token is valid for the performance check-in window if such a window is configured;
- reservation has not already been checked in.
- The backend returns a preview with only the minimum information needed for admission, such as performance, party size, and check-in state.
- Staff confirms check-in in the mobile web page.
- The backend validates the token again server-side.
- The backend creates a
CheckInrecord, or updates an existing incomplete check-in record for the same reservation. - The backend stores the check-in timestamp and authenticated staff user.
- The backend returns a successful check-in response.
- Staff admits the visitor party.
The token remains opaque throughout the flow. The QR code must not expose visitor name, email address, phone number, notes, or other personal data.
Manual Reservations In Admin
Staff can also create a reservation manually from Django admin for a specific performance.
This operational flow should still follow the same backend rules as the public booking flow:
- staff selects the performance and enters guest contact details and party size;
- the backend validates booking availability and capacity;
- the backend creates a
pendingreservation; - the backend creates the normal confirmation token;
- after the reservation transaction commits, the backend sends the standard confirmation email;
- the guest still confirms through the email link before the reservation becomes confirmed and usable for check-in.
Duplicate Check-In
If the same QR code is scanned again:
- The backend detects an existing check-in for the reservation.
- The backend returns
409 Conflict. - The backend does not create a second check-in.
The response should be clear enough for staff to understand that the reservation was already used.
Check-In Failure States
Failed validation must return clear error states without creating a successful check-in.
Expected check-in failures include:
- missing or malformed token;
- unknown token;
- expired token;
- staff user is not authenticated;
- staff user does not have check-in permission;
- reservation is not confirmed;
- reservation was already checked in;
- token is not valid for the selected performance or check-in window.
Capacity Handling
Capacity is calculated as:
room capacity + additional seats - manually occupied seats - confirmed reservations
Only confirmed reservations consume capacity. Pending reservations represent interest, not a guaranteed seat.
To avoid overbooking, final confirmation must be transactional:
- lock the performance;
- recalculate confirmed seats;
- compare availability with requested party size;
- confirm only when seats are available.
Failure States
Expected failure states include:
- invalid booking input;
- booking disabled for the performance;
- no capacity remaining;
- confirmation token expired;
- confirmation token already used;
- QR token invalid;
- reservation not confirmed;
- reservation already checked in.
Each failure should return a clear status code and a concise user-facing message.