You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
CineBook is an advanced, production-scale Movie Reservation System built using the MERN-like stack (MySQL instead of MongoDB). Designed with architectural best practices in mind, this project demonstrates full-stack proficiency, deep understanding of relational database design, real-time concurrency control, responsive user interfaces, and robust state management.
π Key Features & Functionality
1. Robust Concurrency Control (Preventing Double Booking)
A critical feature in any reservation system, CineBook prevents race conditions when two users try to book the exact same seat simultaneously.
Database Transactions & Locks: The checkout flow wraps seat verification and booking insertion inside a strict MySQL Database Transaction (connection.beginTransaction()). If any step fails, the transaction rolls back, guaranteeing data integrity.
Pending Reservation Locking: When a user clicks "Book", the backend checks against currently confirmed bookings AND any pending bookings made within the last 5 minutes. This creates a temporary "lock" on the seat during the payment flow, preventing others from snagging the seat right out from under the user.
2. Intelligent Seat Rendering Engine
Rather than relying on static images, the seat map dynamically constructs itself from the seats and screens tables. The frontend groups individual seats (e.g., A1, A2, B1) contextually by their row_label, applying grid-based CSS. The seat status is merged with the live booking data to visually lock (disable) booked seats on the user's screen in real-time.
3. User & Authentication
Password hashing utilizing bcrypt for secure authentication storing in password_hash.
Context-based global auth (AuthContext with local storage persistence), ensuring users must log in to access the booking and checkout pipelines.
Node.js, Express.js, mysql2 API (with connection pooling), CORS, bcrypt
Database
Relational SQL (MySQL / MariaDB)
ποΈ Relational Database Schema Architecture
The database schema (movie_reservation_system) is highly normalized down to 3NF logic, built to handle scale, multi-screen multiplexes, and precise historical record-keeping.
Core Tables:
movies: Standard metadata catalog. Includes movie_id (PK), title, description, duration, genre, language, release_date, and status (active/removed).
screens & theaters: Accounts for multi-theater architecture. theaters (name, city, address) hold many screens (screen_name, total_seats).
shows: The intersection of mapping a movie to a screen at a specific time. Includes show_id (PK), movie_id (FK), screen_id (FK), show_date, start_time, end_time, and highly-specific dynamic price fields.
seats: The absolute source-of-truth for screen topography. Includes row indexing row_label (char), seat_number (int), and configurable pricing tiers (seat_type: regular, premium, recliner).
bookings: The main reservation order ticket. Tracks user_id, show_id, total_amount, status (pending, confirmed, cancelled), and timestamp.
booking_seats: Resolves the many-to-many relationship of a single booking containing multiple specific seats. Joins booking_id to seat_id.
payments: Handles the financial transaction state attached to a reservation (booking_id). Tracks gateway, transaction_id, amount, and status (success, failed, pending).
π οΈ Installation & Setup Guide
1. Database Setup
Launch your MySQL server instance.
Ensure you have created the movie_reservation_system database and imported the schema exactly as defined above.
Seed your seats table properly for the applicable screens. (A utility seed file seed_seats.js is available in the backend to bulk-insert screen topologies).
Verify credentials in backend/db.js (user, password, host).
2. Backend Server Application
Open your terminal and navigate to the /backend folder.
cd backend
npm install
node server.js
The Express server starts listening on http://localhost:5000. Watch your console for the mysql connected successfully log line.
3. Frontend Client App
Open a separate terminal and navigate to the frontend directory.
cd"cinibook"
npm install
npm run dev
The Vite development server will start the application, typically on http://localhost:8081.
π§ System Workflows (For Interview Discussion)
The Booking Transaction Flow
Pre-flight: User selects a show_id in the UI. Frontend requests live seat status.
View: Backend executes a LEFT JOIN on bookings and booking_seats where status is confirmed/payment pending. The Frontend renders this map.
Action: User selects specific seats and hits "Book".
Validation: Backend opens a MySQL BEGIN TRANSACTION. It re-verifies these exact seats haven't been picked up in the background (SELECT ... FOR UPDATE isolation style patterns or time-based threshold validation).
Soft Lock: If clear, inserts a pending row into bookings and registers the seats in booking_seats.
Payment Phase: Navigates user to Payment confirmation screen. Upon success, an UPDATE flips the booking status to confirmed and issues an INSERT into payments.
(This pipeline guarantees no two users walk away believing they have bought the exact same ticket).
Seat Availability Query Logic
The seat status is determined by a carefully crafted SQL query that joins 3 tables:
SELECTs.seat_id, s.row_label, s.seat_number, s.seat_type,
CASE WHEN b.status='confirmed' THEN 'booked' ELSE 'available' END AS status
FROM seats s
LEFT JOIN booking_seats bs ONs.seat_id=bs.seat_idLEFT JOIN bookings b ONbs.booking_id=b.booking_idANDb.show_id= ? ANDb.status='confirmed'WHEREs.screen_id= ?
This LEFT JOIN approach ensures all seats are returned, with their real-time status calculated dynamically from the bookings and booking_seats tables β not stored as a mutable column.
Password Security
User passwords are never stored in plaintext.
On registration, bcrypt generates a salted hash (bcrypt.hash(password, 10)).
On login, bcrypt.compare() validates the input against the stored password_hash.
The salt rounds (10) provide strong protection against brute-force and rainbow table attacks.
Frontend State Management
React Context API (AuthContext) provides global authentication state across all components.
TanStack React Query handles server state (movies, shows, bookings) with built-in caching, background refetching, and stale-while-revalidate patterns.
Local Storage Persistence: Auth tokens and user data survive page reloads without re-authentication.