A concise RESTful backend built with Node.js (Express) and MongoDB (Mongoose) to power a cinema ticketing demo application.
This API features two core modules:
- User Module: Allows users to browse movies, check seat availability, and purchase tickets.
- Admin Module: Enables administrators to manage cinema locations, movies, and screenings.
Admin credentials:
- Username: NextCinemaRetro-admin
- Password: adminpass1234
There havent been any LLMs used for writing code in this project.
- Seeding functionality is scheduled using node cron. The seeding logic (creating movies, screenings, admins accounts, etc) is implemented in
seed.js. - I've utilized several utility functions:
- ExpressError is an utility class for handling errors in the entire app.
- CatchAsync is an utility function designed to wrap async operations and handle potential exceptions.
- Validation schemas are defined in
joiSchemas.jsand run before interacting with the database. - API endpoints are documented using swagger and jsdoc.
- A Global Error Handler is implemented to respond with appropriate error messages based on the application's environment (production | development).
- The
middlewaresdirectory contains the implementation for Authentication (JWT), Authorization, and internal checks (e.g., a middleware function that validates the time interval for a screening).
- This service powers the application's functionality. For the client-side implementation, please see the Frontend Repository.
- The API is live!
- Please note that as it's hosted on a free tier, there may be a brief delay while the server wakes up on your first request.
- Tech Stack
- Installation and Local Configuration
- Endpoints
- Schemas
- API End-to-End Testing (E2E)
- Contact
- Node.js
- MongoDB Atlas
- Postman
- Docker
- JWT Token
- Stripe
- Express.js
- Mongoose
- jsonwebtoken
- Stripe
- bcryptjs
- cookie-parser
- cors
- express-mongo-sanitize
- express-rate-limit
- helmet
- joi
- node-cron
- swagger-jsdoc
- swagger-ui-express
- dotenv
- jest
- morgan
- supertest
- Node and npm
- A MongoDB database
config.envfile
PORT=
DB_USERNAME=
DB_PASSWORD=
DB_URI=
ACCESS_TOKEN_SECRET=
REFRESH_TOKEN_SECRET=
ADMIN_PASSWORD=
ADMIN_PUBLIC_PASSWORD=
STRIPE_SECRET_KEY=
STRIPE_WEBHOOK_SECRET=
RETURN_TO_STRIPE=Option 1: Clone repo
- Clone the repository
- Run
npm install - Configure
config.envfile insidesrcdirectory - Run
npm run dev
Option 2: Docker deployment
You can explore the available endpoints through the following resources:
- Postman Workspace
- Swagger UI (Includes all endpoints, though some descriptions are currently pending completion)
POST /api/users/login→ Authenticate as a user or an admin.GET /api/cinemas→ Retrieve information for all cinemas.POST /api/tickets/create-checkout-session→ Initiate a Stripe checkout session for ticket purchases.GET /api/users/reports/sales→ Access sales reports (Admin-only access).
(check ./src/models/user.js)
username: Stringpassword: StringrefreshTokens: ArrayrefreshTokens.token: StringrefreshTokens.createdAt: Date
dateOfBirth: Dategender: StringphoneNumber: Stringaddress: StringisAdmin: Boolean
(check ./src/models/auditorium.js)
number: Numbercapacity: Numbertype: String (enum: 'Standard', '4dx', 'IMAX')seatLayout: ObjectseatLayout.rows: NumberseatLayout.seatsPerRow: Number
screenSize: StringsoundSystem: Stringprojection: StringcreatedAt: DateupdatedAt: Date
(check ./src/models/cinema.js)
name: Stringlocation: Stringadmin: ObjectId (ref: User)auditoriums: Array (ref: Auditorium)openingHour: NumberclosingHour: Numberemail: Stringparking: Booleantimestamps: Objecttimestamps.createdAt: Datetimestamps.updatedAt: Date
(check ./src/models/movie.js)
creator: ObjectId (ref: Admin)title: String (required, unique)description: String (required)slug: String (required, unique)duration: Number (required, min: 0)releaseDate: Date (required)genres: Array of String (required, enum: Action, Comedy, Drama, Horror, SF, Fantasy, Thriller, Romance, Adventure, Animation, Documentary)cast: Arraycast.name: String (required)cast.characterName: String (required)
director: String (required)production: String (required)distribution: String (required)coverImage: String (required)trailer: String (required)timestamps: Objecttimestamps.createdAt: Datetimestamps.updatedAt: Date
(check ./src/models/review.js)
author: mongoose.Types.ObjectId (ref: User, required)movie: mongoose.Types.ObjectId (ref: Movie, required)rating: Number (min: 0, max: 5, required)body: String (required)timestamps: truetimestamps.createdAt: Datetimestamps.updatedAt: Date
(check ./src/models/screening.js)
auditorium: ObjectId (ref: Auditorium)movie: ObjectId (ref: Movie)cinema: ObjectId (ref: Cinema)date: DatestartTime: Numberpricing: Numberlanguage: Stringsubtitle: StringcreatedBy: ObjectId (ref: User)timestamps: Boolean
(check ./src/models/ticket.js)
screening: ObjectId (ref: Screening)customer: ObjectId (ref: User)seat: Objectseat.row: Numberseat.number: Number
totalPrice: NumberpricingCategory: String (enum: standard, student)createdAt: DateupdatedAt: Date
These E2E tests are built upon a powerful stack:
- Jest
- Supertest
Currently, E2E tests cover a small but critical subset of endpoints, primarily focusing on read operations (like fetching all Cinemas and Movies) and a write operation (creating a Movie).
For endpoints requiring authentication (like the POST /api/movies route), a mocked authentication token is generated and sent in the request header to simulate an authenticated admin user, allowing the test to verify the functionality protected by authorization.
All E2E test files are located in the repository at: ./src/__test__.
- Email: alexmita04@gmail.com
See LICENSE