CASE STUDY / MEDIA PLATFORM

MovieFy

Active iteration

From a movie review app to a two-sided content platform

A movie content platform for viewers and administrators. React, Tailwind CSS and shadcn/ui shape discovery, playback, cast, reviews and content operations, while Node.js, Express, MongoDB and JWT support the content and authentication paths.

01 / PRODUCT SCOPE

Why does a movie app need two experiences?

MovieFy serves two audiences: viewers who want to discover, watch and review movies, and administrators who maintain movies, actors, media files and user reviews. The challenge was not simply building a movie list, but organising two information hierarchies around one content model: a smooth discovery experience for users and a complex, relational content workspace for administrators.

  • Organise viewer and admin experiences around one movie, actor and review model
  • Handle movie metadata, cast relationships and media uploads through composable forms
  • Support search, playback, ratings, reviews, related movies and localised content
  • Keep interactions consistent across themes, mobile layouts and dense admin tables

02 / MOVIE EXPERIENCE

How a movie moves from content management to viewing

  1. 01

    Discover

    The home page uses a hero carousel, latest uploads and genre-based top-rated lists to help viewers find movies.

  2. 02

    Search

    Viewers search by title while Search Context and debounce logic reduce repeated requests and expose result states.

  3. 03

    Explore

    The movie detail page brings together video, story, director, writer, cast, genres, language, release date and related movies.

  4. 04

    Review

    Signed-in viewers can submit ratings, read reviews, and edit or remove their own review.

  5. 05

    Operate

    Administrators use the dashboard, movies, actors and search screens to manage media, people and publication status.

03 / ENGINEERING DECISIONS

Frontend and full-stack decisions visible in the code

  1. 01

    Use composable forms for complex movie data

    ImplementationMovieForm combines React Hook Form and Zod for title, storyline, genres, tags, director, writer, cast, release date, language, status, poster and video fields.

    ValueA form that could easily become unmaintainable is split into validated fields and reusable selectors, with shared interaction for create and edit modes.

  2. 02

    Connect cast relationships through debounced search

    ImplementationLiveSearch, LiveSearchCast, DirectorSelector and WriterSelector provide live search, keyboard navigation, multi-select presentation and duplicate filtering for people relationships.

    ValueAdministrators can build movie relationships during content entry instead of manually finding and entering database identifiers.

  3. 03

    Treat viewer and admin surfaces as two product experiences

    ImplementationApp switches between the user routes and AdminNavigator based on the authenticated role. The user side centres on discovery, playback and reviews, while the admin side centres on dashboards, movies and actors.

    ValueEach audience gets an appropriate information hierarchy, navigation and interaction density while sharing movie, actor and review APIs.

  4. 04

    Make media upload part of content publishing

    ImplementationThe backend receives images and videos through Multer, uploads them to Cloudinary, and stores URLs, public IDs and responsive poster variants. The frontend validates file types and sizes in the form.

    ValueMovies are more than text CRUD: posters, video assets, CDN resources and metadata move through one publishing workflow.

  5. 05

    Use Context boundaries for cross-page state

    ImplementationAuthProvider restores login state and tokens, MoviesProvider handles paginated movie data, SearchProvider manages search results and ThemeProvider persists the selected theme.

    ValueShared authentication, search, movie list and theme state have explicit boundaries instead of being recreated independently on every page.

  6. 06

    Batch rating aggregation for list views

    ImplementationMongoDB aggregation calculates average ratings, review counts, related movies and top-rated movies. getAverageRatingsMap combines multiple rating lookups into one aggregation instead of repeating a query per movie.

    ValueThe flexible document model remains useful while homepage lists and related content get a more controlled data access path.

04 / CURRENT BOUNDARIES

Backend and state boundaries that still need to converge

The frontend product and content flows have a clear shape, while authentication safety, data consistency and error contracts remain the next engineering focus.

  1. High priority

    JWT storage and lifecycle need strengthening

    The frontend currently stores the JWT in localStorage, while the backend does not visibly set an expiry, refresh or revocation strategy when signing tokens. HttpOnly cookies, short-lived access tokens and refresh-token rotation should be evaluated next.

  2. High priority

    Email verification is not enforced by the review endpoint

    The project implements OTP email verification and an isVerified field, but the review controller still contains a commented verification check. Reviews should not be described as restricted to verified users yet.

  3. Medium priority

    Review and movie references lack a transaction boundary

    Adding or removing a review updates both the Review document and Movie.reviews array, but there is no MongoDB session transaction or unique index to guard concurrent duplicate reviews and partial failures.

  4. Medium priority

    Error contracts and status codes are not fully consistent

    Some validation failures return an error payload with a successful status, while JWT failures need explicit mapping to authentication errors. The frontend currently consumes mostly string errors through toast notifications.

  5. Medium priority

    Frontend server state and search state are simplified

    Several Context providers and module-level pagination or debounce variables hold state. As the dataset grows, server state can move to React Query and search or pagination state can become URL-addressable.

05 / NEXT ITERATION

What to improve next

  1. 01

    Move JWT authentication to a secure, expiring cookie strategy with refresh and revocation support

  2. 02

    Enforce email verification in the review endpoint and add a unique owner-plus-movie constraint

  3. 03

    Use a MongoDB session transaction to keep Review and Movie references consistent

  4. 04

    Unify 4xx/5xx error codes and localised frontend messages, with request-level structured logs

  5. 05

    Move movie, search and pagination data to React Query and add end-to-end viewer and admin flows