Entertainment
Movie and TV Series Watchlist with a Node.js API
A full-stack watchlist app for browsing popular movies and TV series and bookmarking titles to watch later.

Overview
Entertainment is a full-stack web application for browsing popular movies and TV series and building a personal watchlist. Users create an account, explore trending and recommended titles, search the catalog, and bookmark the movies and series they want to watch later. The frontend is built with React and TypeScript, and the backend is a REST API built with Express and MongoDB.
The problem
Movies and series to watch are often scattered across notes, screenshots, and streaming apps. Without a single place to collect them, it is easy to forget recommendations or lose track of titles you planned to watch.
The solution
Entertainment brings a catalog of popular movies and TV series into one interface. Users can browse by category, search instantly, open detail pages, and save titles to a personal bookmarks list tied to their account.
Key features
Trending and Recommendations
The dashboard highlights trending titles in a horizontally scrolling row, followed by a list of recommended movies and series.
Movies and TV Series Catalog
Browse dedicated pages for movies and TV series, populated with popular titles from The Movie Database (TMDB).
Instant Search
Filter the current page as you type, with a search bar that adapts to the section you are browsing.
Detail Pages
Open a title to see its poster, release year, original language, and overview.
Bookmarks
Bookmark movies and series from any card or detail page, and find them grouped on a personal bookmarks page.
User Accounts
Register and log in with an email and password to access the catalog and keep bookmarks tied to your account.
Tech stack
Testing
Services & hosting
Technical implementation
REST API with Express
The backend exposes versioned endpoints for authentication, movies, series, bookmarks, and users, organized into routes, controllers, models, and middleware.
MongoDB Data Modeling
Mongoose models store users, movies, series, and bookmarks, with a unique compound index that prevents the same title from being bookmarked twice.
Data Seeding from TMDB
A seed script fetches popular movies and TV series from the TMDB API, removes duplicates, builds poster and backdrop URLs, and inserts them into MongoDB.
Security and Testing
The API restricts allowed origins with CORS, adds Helmet's XSS protection header, and is tested with Mocha and Chai.
Challenges & engineering decisions
Bookmarking Two Types of Content
Problem
Movies and TV series are stored in separate collections, but users needed a single bookmarking system for both.
Solution
Designed a bookmark model with a content type field and a polymorphic reference, plus a model method that tells the API whether a title is bookmarked by the current user.
Keeping the Interface Responsive
Problem
Waiting for the server after every bookmark click made the interface feel slow, and the same titles appear on several pages.
Solution
Used TanStack Query optimistic updates to change the cached lists immediately, then invalidated the related queries to resync with the server.
Protecting Content Behind Authentication
Problem
The catalog and bookmarks should only be accessible to logged-in users, and expired sessions needed to be handled cleanly.
Solution
Added a JWT verification middleware to all content routes and an Axios response interceptor that redirects users to the login page when a request is unauthorized.
Results & lessons learned
Results
Built a working full-stack watchlist application that combines a React and TypeScript client with an Express and MongoDB API, user authentication, search, and personal bookmarks.
Lessons learned
- Splitting an Express API into routes, controllers, models, and middleware keeps it easy to extend.
- A polymorphic reference can let one model serve several content types instead of duplicating logic.
- Authentication has to be handled on both sides: middleware protects the API, and the client must react cleanly when a session expires.
- Optimistic updates make an interface feel instant, as long as the cache is resynced with the server afterwards.


