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
- 01
Discover
The home page uses a hero carousel, latest uploads and genre-based top-rated lists to help viewers find movies.
- 02
Search
Viewers search by title while Search Context and debounce logic reduce repeated requests and expose result states.
- 03
Explore
The movie detail page brings together video, story, director, writer, cast, genres, language, release date and related movies.
- 04
Review
Signed-in viewers can submit ratings, read reviews, and edit or remove their own review.
- 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
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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
- 01
Move JWT authentication to a secure, expiring cookie strategy with refresh and revocation support
- 02
Enforce email verification in the review endpoint and add a unique owner-plus-movie constraint
- 03
Use a MongoDB session transaction to keep Review and Movie references consistent
- 04
Unify 4xx/5xx error codes and localised frontend messages, with request-level structured logs
- 05
Move movie, search and pagination data to React Query and add end-to-end viewer and admin flows