VideoHub is built as a decoupled, two-layer application living in a single monorepo. The Backend is a Node.js/Express 5 REST API that owns all business logic, authentication, and database access. The Frontend is a React 19 + Vite single-page application that communicates with the backend exclusively through HTTP. The two layers share no runtime code, which means they can be deployed, scaled, and iterated on independently.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/barcode8/VideoHub/llms.txt
Use this file to discover all available pages before exploring further.
Directory Structure
index.js is the application entry point. It loads environment variables via dotenv, ensures the public/temp directory exists (creating it if absent), connects to MongoDB through connectDB(), and then starts the HTTP server. The Express app itself is configured separately in app.js, which registers the middleware stack and mounts all route modules — keeping server lifecycle concerns separate from application configuration.
API Route Structure
All API routes are versioned under/api/v1. The following base paths are mounted in app.js:
| Base path | Responsibility |
|---|---|
/api/v1/healthcheck | Server liveness probe |
/api/v1/users | Registration, login, profile, token refresh |
/api/v1/videos | Upload, fetch, update, delete, publish toggle |
/api/v1/likes | Like / unlike videos, comments, and community posts |
/api/v1/comments | Add, edit, and delete comments on videos |
/api/v1/subscriptions | Subscribe / unsubscribe to channels |
/api/v1/playlist | Create and manage playlists |
/api/v1/dashboard | Channel statistics and video management view |
/api/v1/view | Record and retrieve video view counts |
Request Lifecycle
Every inbound request travels through the same layered stack before a response is sent:CORS & Cookie Parser
cors validates the Origin header against CORS_ORIGIN and, when credentials: true, allows cookies to be included in cross-origin requests. cookie-parser then populates req.cookies so subsequent middleware can read accessToken directly.Body Parsing
express.json() (16 kb limit) and express.urlencoded() parse the request body into req.body. File payloads bypass both and are handled by the Multer middleware on the individual route.Route Matching
Express matches the request path to one of the mounted routers and hands it off to the relevant route handler chain.
Auth Middleware
Protected routes run
verifyJwt, which extracts the JWT from req.cookies.accessToken or the Authorization: Bearer header, verifies it against ACCESS_TOKEN_SECRET, and attaches the resolved user document to req.user. Routes that display different content to authenticated vs. guest users run verifyJWTIfAvailable instead — it follows the same flow but silently continues on any failure.Controller
The controller function executes business logic: validating inputs, running Mongoose queries or aggregation pipelines against MongoDB, orchestrating Cloudinary uploads where relevant, and constructing the final response.
Response Format
Every successful response and every error produced by the API conforms to a predictable shape, constructed byApiResponse and ApiError respectively.
Success — ApiResponse
ApiError
ApiError extends the native Error class. When no custom stack string is provided the constructor calls Error.captureStackTrace so that V8 stack frames point to the throw site, not to internal Error internals.
asyncHandler wraps every controller in a try/catch. When a controller throws an ApiError (or any error), asyncHandler catches it and calls res.status(error.statusCode || 500).json(...) directly — it does not call Express’s next() and does not rely on a downstream error-handling middleware.
Data Models
VideoHub’s MongoDB collections map to the following Mongoose models:User
Stores credentials (bcrypt-hashed password), profile metadata (avatar, cover image, fullName), watch history references, and the persisted refresh token.
Video
Tracks the Cloudinary video and thumbnail URLs, duration, publish status (
isPublished), owner reference, and view count.Comment
Links a text body to a parent video and the author User.
Like
Polymorphic — a single Like document can reference a video, a comment, or a community post via nullable foreign keys.
Subscription
Represents a follower → channel relationship between two User documents.
Playlist
Belongs to an owner User and holds an ordered array of Video references.
View
Records individual video view events, enabling deduplication and analytics.
Community (Tweet)
Short-form text posts published on a user’s channel page, modelled similarly to tweets.