5.7 KiB
Domain Model
This document describes the core domain concepts for AzioneLab's theatre website and booking system.
Show
A show is a theatrical production presented by the company.
Suggested fields:
id: internal identifier;title: public show title;slug: stable public URL identifier;summary: short public description;description: full public description;poster_image: optional public image;is_published: controls public visibility;created_at: creation timestamp;updated_at: last update timestamp.
Relationships:
- one show can have many performances.
Rules:
- unpublished shows are not listed publicly;
- a public show detail page may include only published upcoming performances.
Venue
A venue is the place where a performance happens.
Suggested fields:
id: internal identifier;name: public venue name;slug: stable public URL identifier;address: public address;city: venue city;notes: optional public or internal venue notes;created_at: creation timestamp;updated_at: last update timestamp.
Relationships:
- one venue can host many performances.
Performance
A performance is a scheduled presentation of one show at one venue.
Suggested fields:
id: internal identifier;show: required reference toShow;venue: required reference toVenue;starts_at: performance date and time;room_capacity: configured total room capacity;manually_occupied_seats: seats unavailable because they are reserved outside the public booking system;additional_seats: optional extra seats made available during booking;is_booking_enabled: controls whether public booking is open;created_at: creation timestamp;updated_at: last update timestamp.
Relationships:
- each performance belongs to one show;
- each performance belongs to one venue;
- one performance can have many reservations.
Availability formula:
available seats =
room capacity
+ additional seats
- manually occupied seats
- confirmed reservations
Rules:
- capacity values must not be negative;
manually_occupied_seatsmust not exceedroom_capacity + additional_seats;- only confirmed reservations reduce public availability;
- pending reservations do not guarantee a seat until confirmation;
- final capacity validation must happen server-side when confirming a reservation;
- changes to capacity configuration must preserve existing confirmed reservations.
Reservation
A reservation is a booking request for a specific performance.
Suggested fields:
id: internal identifier;performance: required reference toPerformance;status: explicit status such aspending,confirmed,cancelled, orexpired;name: reservation contact name;email: reservation contact email;phone: optional reservation contact phone;party_size: number of requested seats;notes: optional visitor note;confirmed_at: timestamp set when the reservation is confirmed;qr_code_generated_at: timestamp set when the QR code is generated;created_at: creation timestamp;updated_at: last update timestamp.
Relationships:
- each reservation belongs to one performance;
- one reservation can have one or more reservation tokens for different purposes;
- one confirmed reservation can have at most one successful check-in.
Rules:
- a new reservation starts as
pending; - a reservation becomes
confirmedonly through a valid confirmation token; - a confirmed reservation receives a QR code;
party_sizemust be positive;- the backend must reject confirmation if the requested seats would exceed availability;
- personal data must never be stored in QR codes.
ReservationToken
A reservation token is an opaque token used for confirmation or QR verification.
Suggested fields:
id: internal identifier;reservation: required reference toReservation;purpose: token purpose, such asconfirmationorcheck_in;token_hash: server-side hash of the opaque token;expires_at: optional expiration timestamp;used_at: timestamp set when a one-time token is consumed;created_at: creation timestamp.
Relationships:
- each token belongs to one reservation.
Rules:
- raw tokens must be random, non-guessable, and generated with a cryptographically secure generator;
- store only a hash of the token when practical;
- confirmation tokens should be single use;
- QR tokens may remain valid until the performance check-in window closes;
- tokens must not encode personal data.
CheckIn
A check-in records entrance validation for a confirmed reservation.
Suggested fields:
id: internal identifier;reservation: required unique reference toReservation;checked_in_at: timestamp of successful check-in;checked_in_by: optional authenticated staff user reference;source: optional source such asqr_scanormanual;created_at: creation timestamp.
Relationships:
- each check-in belongs to one reservation;
- a reservation can have at most one successful check-in.
Rules:
- only confirmed reservations can be checked in;
- a reservation cannot be checked in twice;
- failed check-in attempts should return a clear status without changing successful check-in state;
- check-in must not expose unnecessary personal data to scanning clients.
Anti-Overbooking Rule
The backend must enforce capacity inside a transaction when confirming reservations.
Recommended approach:
- lock the relevant
Performancerow during confirmation; - count confirmed seats for that performance;
- compare requested seats with available seats;
- confirm only if enough seats remain;
- otherwise leave the reservation pending or mark it as expired/rejected according to the future product decision.