GitHub - Mineru98/MiniFlix
Key Points
- 1MiniFlix is a web-based streaming service that replicates core Netflix functionalities, enabling users to stream content, browse titles by search or genre, and manage personal wishlists.
- 2The system supports comprehensive user features, including registration, login with JWT authentication, account management, and tracking viewing history with resume playback capabilities.
- 3Architected with a Next.js/React frontend and a Golang/Gin backend backed by MySQL, the platform emphasizes responsive design and is deployed using Docker Compose.
MiniFlix is a web-based streaming service that streamlines the core functionalities of platforms like Netflix, offering content streaming, browsing, user management, and a wishlist feature with a responsive design.
The system's architecture is visualized through a comprehensive screen flow, an Entity-Relationship Diagram (ERD), and detailed sequence diagrams for key functionalities. The screen flow outlines user navigation across various pages: a non-logged-in landing page, authentication pages (login, signup), the main home screen displaying content, content-related pages (search results, genre-filtered lists, content details, video player), and user-specific pages (My Page, Wishlist, Account Info). All content-related pages and user pages allow navigation back to the home screen.
The database schema, defined by the ERD, comprises six main entities:
- Users: Stores user information including
id(PK),email(login ID),password_hash,name,created_at,updated_at, andis_active(account status). - Contents: Holds details for each video content, such as
id(PK),title,description,thumbnail_url,video_url,duration,release_year,created_at, andupdated_at. - Genres: Defines content categories with
id(PK),name, anddescription. - ContentGenres: A mapping table (junction table) linking
ContentsandGenreswithid(PK),content_id(FK), andgenre_id(FK). - Wishlists: Records contents saved by users, including
id(PK),user_id(FK to Users),content_id(FK to Contents), andcreated_at. - ViewingHistories: Tracks user viewing activity, containing
id(PK),user_id(FK to Users),content_id(FK to Contents),watch_duration,last_position,watched_at, andis_completed.
Relationships are defined as follows: A User can have multiple Wishlists and ViewingHistories. A Content can be in multiple Wishlists, multiple ViewingHistories, and be categorized by multiple ContentGenres. A Genre can classify multiple ContentGenres.
The core methodology is detailed through several sequence diagrams illustrating interactions between the Client (browser), Backend API Server, Database (DB), and Media Storage.
- User Registration: The Client sends email, password, and name to the API. The API validates the data, queries the
Userstable for email duplication. If unique and valid, the password is hashed, and the user's information (email, password\_hash, name, created\_at, is\_active=1) is saved to theUserstable. Responses include409 Conflict(email duplicate),400 Bad Request(validation failure), or201 Createdon success, followed by redirection to the login page.
- Login: The Client sends email and password. The API queries the
Userstable for the user's information (id, password\_hash, name, is\_active) by email. If the user doesn't exist (401 Unauthorized) or is inactive (403 Forbidden), an error is returned. If found, the API verifies the provided password against the storedpassword_hash. Upon successful verification, a JSON Web Token (JWT) containing user ID and name is generated and returned with200 OKalong with basic user info. The Client stores the JWT (e.g., in localStorage/cookies) and redirects to the home screen.
- Home Screen Content Load: When accessing the home screen, if logged in, the Client sends an authenticated request (with JWT) to the API. The API validates the JWT. If valid, it queries the
Contentstable for basic content information (id, title, thumbnail\_url, release\_year). It also queries theWishliststable to retrieve the user's liked content IDs and then merges this information to addis_likedstatus to each content item before returning the200 OKresponse. If the JWT is invalid (401 Unauthorized), the client is redirected to login. For non-logged-in users, the Client sends an unauthenticated request, and the API directly returns content basic info from theContentstable withoutis_likedstatus.
- Content Search: The Client sends a search query (and an optional JWT). The API queries the
Contentstable for titles matchingLIKE '%๊ฒ์์ด%'. If logged in, the API also fetches the user'sWishliststo indicate liked content in search results. The API returns200 OKwith the matching content list (or an empty array if no results).
- Genre Filtering: The Client first requests a list of genres from the API, which queries the
Genrestable and returns them for UI display. Upon user selection of a genre, the Client requests content for the chosengenre_id(with optional JWT). The API joinsContentsandContentGenrestables to filter bygenre_id. Similar to search, if logged in,Wishlistsare checked to addis_likedstatus to the filtered content list.
- Content Details View: When a content thumbnail is clicked, the Client requests detailed information for a
content_id(with optional JWT). The API queriesContents,ContentGenres, andGenrestables to retrieve full content details and associated genres. If logged in, it also checks theWishliststable for the content's like status andViewingHistoriesfor thelast_position(last watched point). The API returns200 OKwith detailed info, like status, and last position (if applicable).
- Content Playback: If a user attempts to play content while not logged in, they are redirected to the login page. If logged in, the Client sends a playback request (with
content_id, JWT). The API validates the JWT, retrievesvideo_urlfromContentsandlast_positionfromViewingHistories. The API then returns the streaming URL and last position. The Client requests the video stream from the Media Storage. During playback, the Client periodically updates the API (every 30 seconds) withcurrent_positionwhich the API saves toViewingHistories. Upon playback termination (pause, window close), the Client sends a final update (final\_position, watch\_duration, is\_completed), which the API saves.
- Wishlist Toggle: If not logged in, clicking the like button redirects to login. Otherwise, the Client sends a toggle request (with
content_id, JWT). The API validates the JWT and checks theWishliststable for the current like status. If already liked, it deletes the entry fromWishlists(200 OK,is_liked: false). If not liked, it adds an entry toWishlists(201 Created,is_liked: true). The Client updates its UI accordingly.
- Wishlist View: From My Page, the Client requests the wishlist (with JWT). The API validates the JWT, then joins
WishlistsandContentstables to retrieve the details of all liked contents for the user. Returns200 OKwith the list of contents or an empty array.
- Account Information View: From My Page, the Client requests account info (with JWT). The API validates the JWT, queries the
Userstable for the user'semail,name, andcreated_at, and returns200 OKwith this information.
- Account Information Update: The Client sends updated name or password (and current password for verification, JWT). The API validates the JWT and verifies the
current_passwordagainst the storedpassword_hashinUsers. If the current password matches and new data is valid (new password is hashed if provided), theUserstable is updated (name,password_hash,updated_at). Returns200 OKon success,403 Forbiddenfor incorrect current password, or401 Unauthorizedfor invalid JWT.
The project utilizes a modern technology stack:
- Frontend: TypeScript, React, Next.js, Zustand (state management), React Query (server state management), TailwindCSS (styling), and Axios (HTTP client).
- Backend: Golang with the Gin framework, MySQL as the database, JWT for authentication, and Swagger for API documentation.
- Deployment: Docker Compose for easy setup and management.
The application can be accessed via http://localhost:3000 for the frontend, http://localhost:8080 for the backend API, and http://localhost:8080/swagger/index.html for the API documentation, enabling both local development and deployment.