generated from bisco/codex-bootstrap
181 lines
7.0 KiB
Markdown
181 lines
7.0 KiB
Markdown
# Booking Flow
|
|
|
|
This document describes the full public booking, confirmation, QR generation, and entrance check-in flow.
|
|
|
|
## 1. Public Discovery
|
|
|
|
1. A visitor opens the public website.
|
|
2. The Angular frontend requests published shows and upcoming performances from the backend.
|
|
3. The visitor opens a show detail page.
|
|
4. 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
|
|
|
|
1. The visitor selects a performance.
|
|
2. The frontend displays the booking form for that performance.
|
|
3. The visitor enters contact details and party size.
|
|
4. The frontend submits the booking request to the backend.
|
|
5. The backend validates:
|
|
- required fields;
|
|
- email format;
|
|
- positive party size;
|
|
- performance exists and booking is open;
|
|
- requested seats do not exceed currently available seats.
|
|
6. The backend creates a `pending` reservation.
|
|
7. The backend creates a random opaque confirmation token.
|
|
8. After the transaction commits successfully, the backend sends an email with a confirmation link.
|
|
9. The frontend tells the visitor to check their email.
|
|
|
|
The reservation is not confirmed at this stage.
|
|
|
|
## 3. Email Confirmation
|
|
|
|
1. The visitor opens the confirmation link from the email.
|
|
2. The frontend or backend submits the confirmation token to the confirmation endpoint.
|
|
3. The backend validates that the token:
|
|
- exists;
|
|
- has the `confirmation` purpose;
|
|
- belongs to a pending reservation;
|
|
- has not expired;
|
|
- has not already been used.
|
|
4. The backend starts a database transaction.
|
|
5. The backend locks the related performance row.
|
|
6. The backend recalculates confirmed reservations for the performance.
|
|
7. The backend confirms the reservation only if enough seats remain.
|
|
8. The backend marks the confirmation token as used.
|
|
9. The backend creates a separate `check_in` token for QR verification.
|
|
10. The backend generates a QR code containing only the opaque check-in token or a verification URL built from that token.
|
|
11. 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
|
|
|
|
1. Staff signs in with an account that has check-in permission.
|
|
2. Staff opens a mobile-friendly web page for entrance check-in.
|
|
3. Staff scans the visitor's QR code with the device camera or enters the QR token manually.
|
|
4. The QR code provides only an opaque check-in token or verification URL.
|
|
5. The frontend submits the token to the backend for a verification preview.
|
|
6. The backend validates:
|
|
- staff authentication and permission;
|
|
- token exists and has the `check_in` purpose;
|
|
- 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.
|
|
7. The backend returns a preview with only the minimum information needed for admission, such as performance, party size, and check-in state.
|
|
8. Staff confirms check-in in the mobile web page.
|
|
9. The backend validates the token again server-side.
|
|
10. The backend creates a `CheckIn` record, or updates an existing incomplete check-in record for the same reservation.
|
|
11. The backend stores the check-in timestamp and authenticated staff user.
|
|
12. The backend returns a successful check-in response.
|
|
13. 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:
|
|
|
|
1. staff selects the performance and enters guest contact details and party size;
|
|
2. the backend validates booking availability and capacity;
|
|
3. the backend creates a `pending` reservation;
|
|
4. the backend creates the normal confirmation token;
|
|
5. after the reservation transaction commits, the backend sends the standard confirmation email;
|
|
6. the guest still confirms through the email link before the reservation becomes confirmed and usable for check-in.
|
|
|
|
For operational testing or guest-support exceptions, Django admin also provides staff-only manual tools:
|
|
|
|
1. staff may confirm a pending reservation from the reservation admin page;
|
|
2. manual confirmation still rechecks booking availability before confirming;
|
|
3. the backend generates the same `check_in` token type used by the normal confirmation flow;
|
|
4. admin can generate a one-time operational QR code and check-in URL without showing token hashes in normal admin screens;
|
|
5. staff may mark a confirmed reservation as checked in from admin when the browser/mobile check-in flow is unavailable.
|
|
|
|
## Duplicate Check-In
|
|
|
|
If the same QR code is scanned again:
|
|
|
|
1. The backend detects an existing check-in for the reservation.
|
|
2. The backend returns `409 Conflict`.
|
|
3. 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:
|
|
|
|
```text
|
|
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:
|
|
|
|
1. lock the performance;
|
|
2. recalculate confirmed seats;
|
|
3. compare availability with requested party size;
|
|
4. 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.
|