Project Documentation
π 1. Overview
Comprehensive Project Overview: SOB (Social Online Broadcast) Backend
Project Purpose
The SOB (Social Online Broadcast) backend is a scalable, real-time, and secure Node.js API designed to power a social media platform with multimedia sharing, user authentication, and live interaction capabilities. The system integrates Google OAuth for authentication, Cloudinary for media storage, MongoDB for data persistence, and Socket.IO for real-time communication, making it suitable for applications requiring instant updates (e.g., live chats, notifications, or streaming). The project emphasizes security (JWT, rate limiting, Helmet), performance (compression, CORS), and scalability (MongoDB, Mux for video processing).
The backend is structured to support a React-based frontend (as inferred from CLIENT_URL in .env.example), enabling features like:
- User authentication (JWT, OAuth, email/password)
- Media uploads (Cloudinary, Multer)
- Real-time interactions (Socket.IO)
- Email notifications (Nodemailer)
- Rate-limited API endpoints (express-rate-limit)
- Secure headers (Helmet)
Core Tech Stack
The backend leverages a modern JavaScript/TypeScript stack with the following key technologies:
| Category | Technology | Purpose |
|---|---|---|
| Runtime | Node.js (ESNext) | Server-side JavaScript runtime for high-performance I/O operations. |
| Framework | Express.js | Minimalist web framework for routing, middleware, and API endpoints. |
| Database | MongoDB (Mongoose ODM) | NoSQL database for flexible, schema-less data storage (user profiles, posts, etc.). |
| Authentication | JWT, Passport, Google OAuth | Secure user authentication with access/refresh tokens and OAuth2 integration. |
| Real-Time Engine | Socket.IO | Enables bidirectional event-based communication (e.g., live chats, notifications). |
| Media Handling | Cloudinary, Multer, Mux | Cloud-based image/video storage (Cloudinary), file uploads (Multer), and video processing (Mux). |
| Security | Helmet, express-rate-limit | Protects against XSS, CSRF, and brute-force attacks. |
| Nodemailer | Sends transactional emails (e.g., password resets, notifications). | |
| Environment | dotenv | Manages configuration via .env files. |
| Development | Nodemon | Auto-restarts the server during development. |
Primary Problem Solved
The SOB backend addresses the challenges of building a modern social media platform by providing:
-
Unified Authentication System
- Supports email/password, Google OAuth, and JWT-based sessions for seamless user onboarding.
- Refresh tokens (
JWT_REFRESH_EXPIRES=7d) ensure long-lived sessions without repeated logins.
-
Real-Time Engagement
- Socket.IO enables features like live chats, notifications, and collaborative updates (e.g., comments, reactions) without polling.
-
Scalable Media Management
- Cloudinary handles image/video uploads with CDN delivery, while Mux processes video streams for optimized playback.
- Multer manages file uploads before offloading to Cloudinary.
-
Security & Compliance
- Helmet secures HTTP headers (e.g.,
X-Frame-Options,Content-Security-Policy). - Rate limiting (
express-rate-limit) prevents abuse (e.g., brute-force attacks). - Environment variables (
.env.example) ensure secrets (e.g., JWT secrets, DB URIs) are never hardcoded.
- Helmet secures HTTP headers (e.g.,
-
Developer Experience
- ESNext modules (
jsconfig.json) enable modern JavaScript features. - Nodemon streamlines development with automatic server restarts.
- ESNext modules (
Architectural Highlights
- Modular Design: The backend follows a MVC-like structure (routes, controllers, models) for maintainability.
- Event-Driven: Socket.IO facilitates real-time updates (e.g., new messages, friend requests).
- Cloud-Native: Cloudinary and Mux offload media processing to third-party services, reducing server load.
- Type Safety: While not explicitly using TypeScript, the
jsconfig.jsonhints at potential future adoption.
Potential Use Cases
The SOB backend is ideal for:
- Social networks (e.g., Twitter/X-like microblogging with media).
- Live streaming platforms (via Mux integration).
- Collaborative apps (e.g., real-time document editing with chat).
- Community forums with user-generated content and notifications.
Key Observations
- No Frontend Code: The repository appears to be backend-only, suggesting a decoupled architecture where the frontend (likely React) consumes this API.
- Video Focus: The inclusion of Mux (
@mux/mux-node) implies video upload/streaming capabilities, differentiating it from text/image-only platforms. - Enterprise-Grade: Features like rate limiting, JWT refresh tokens, and Helmet indicate a production-ready system.
This backend is a robust foundation for a social platform requiring real-time interaction, media handling, and security.
π 2. Project Structure
Codebase File Structure Analysis
The provided codebase appears to follow a modular architecture with separate folders for configuration, controllers, middlewares, models, routes, socket handling, and utilities.
Below is a detailed Markdown table categorizing the files and their key responsibilities:
| Category | Sub-folder | Key Responsibility |
|---|---|---|
| Environment | root | Configuration and setup files for the project environment |
| Authentication | src/config | Configuration for passport and authentication-related services |
| Authentication | src/controllers | Handling authentication-related requests and business logic |
| Authentication | src/middlewares | Authentication middleware for verifying requests |
| Database Models | src/models | Definition of database schema and models |
| API/Services | src/controllers | Handling requests and business logic for various API endpoints |
| API/Services | src/routes | Definition of API endpoint routes |
| API/Services | src/middlewares | Middleware for handling requests and responses |
| State Management | src/app.js, src/socket/socket.js | Management of application state and real-time communication |
| UI Components | None | No explicit UI component files found; may be handled by frontend framework or separate repository |
| Utils | src/utils | Utility functions for API responses, token generation, email sending, and push notifications |
| Configuration | src/config | Configuration for database, cloudinary, nodemailer, and other services |
| Configuration | src/config | Environment variable validation and setup |
| Server | root, src | Setup and configuration for the server |
Architectural Patterns
The codebase seems to follow a combination of the Model-View-Controller (MVC) and Model-View-Router (MVR) architectural patterns. Here's a breakdown of the patterns observed:
- MVC Pattern:
- Model: Defined in
src/models, these represent the data structures and schema for the database. - View: Although not explicitly defined, the views are likely handled by a frontend framework or separate repository, with the
src/controllersacting as an intermediary for data processing and presentation logic. - Controller: Found in
src/controllers, these handle requests, interact with models, and return responses to the client.
- Model: Defined in
- MVR Pattern:
- Model: Same as in the MVC pattern, defined in
src/models. - View: Similar to the MVC pattern, the views are not explicitly defined but likely handled by a frontend framework or separate repository.
- Router: Defined in
src/routes, these handle the mapping of client requests to specific controller actions.
- Model: Same as in the MVC pattern, defined in
Additionally, the codebase exhibits elements of Onion Architecture (also known as Clean Architecture), with the following layers:
- Entities (Domain Model): Represented by the database models in
src/models. - Use Cases (Application Logic): Implemented in
src/controllersandsrc/middlewares. - Interface Adapters: Defined in
src/routesandsrc/middlewares. - Frameworks and Drivers: Utilized in
src/configfor database, cloudinary, and other service configurations.
Overall, the codebase employs a modular and layered architecture, combining elements of MVC, MVR, and Onion (Clean) Architecture to maintain separation of concerns and promote scalability.
ποΈ 3. Architecture & Data Flow
Deep-Dive Architecture Analysis: SOB Backend
1. Architecture Reasoning & Module Interactions
This repository represents a Node.js/Express.js backend for a social media application (SOB - "Social On Board"). The architecture follows a layered, modular design with clear separation of concerns, leveraging MVC (Model-View-Controller) and middleware-based request processing. Below is a detailed breakdown of the architectural layers, design patterns, and module interactions.
1.1. High-Level Architecture Overview
The system is structured into the following logical layers:
| Layer | Purpose | Key Components |
|---|---|---|
| Configuration | Centralized environment and service configuration | src/config/*.js, .env.example, jsconfig.json |
| Models | Data layer (Mongoose schemas & business logic) | src/models/*.js |
| Controllers | Business logic & request handling | src/controllers/*.js |
| Routes | API endpoint definitions & route handlers | src/routes/*.js |
| Middlewares | Cross-cutting concerns (auth, validation, uploads, etc.) | src/middlewares/*.js |
| Utilities | Reusable helper functions & services | src/utils/*.js |
| Real-Time | WebSocket-based real-time communication | src/socket/socket.js |
| Entry Points | Application startup & server initialization | server.js, src/app.js |
1.2. Core Design Patterns & Principles
1.2.1. Dependency Injection (DI) via Config Modules
- Pattern: Service Locator / DI Container
- Implementation:
- Configuration files (
cloudinary.js,db.js,nodemailer.js, etc.) act as singleton services that are imported and reused across the application. - Example:
// src/config/cloudinary.js import { v2 as cloudinary } from 'cloudinary'; import dotenv from 'dotenv'; dotenv.config(); const cloudinaryConfig = cloudinary.config({ cloud_name: process.env.CLOUDINARY_CLOUD_NAME, api_key: process.env.CLOUDINARY_API_KEY, api_secret: process.env.CLOUDINARY_API_SECRET, }); export default cloudinaryConfig; - Why?
- Decouples configuration from business logic.
- Centralizes third-party service initialization (Cloudinary, Mux, Nodemailer, etc.).
- Easier to mock in tests.
- Configuration files (
1.2.2. Middleware Pipeline (Chain of Responsibility)
- Pattern: Middleware Chain
- Implementation:
- Express.js middleware functions are composed in a pipeline where each middleware can:
- Modify the request/response.
- Short-circuit the request (e.g., auth failure).
- Pass control to the next middleware.
- Example:
// src/app.js import express from 'express'; import authMiddleware from './middlewares/auth.middleware.js'; import postRoutes from './routes/post.routes.js'; const app = express(); app.use(express.json()); app.use(authMiddleware.authenticate); // Auth middleware runs first app.use('/api/posts', postRoutes); // Post routes run after auth - Key Middlewares:
auth.middleware.js: JWT validation & user attachment.admin.middleware.js: Role-based access control.upload.middleware.js: Multer-based file upload handling.validate.middleware.js: Express-validator-based request validation.
- Express.js middleware functions are composed in a pipeline where each middleware can:
1.2.3. Repository Pattern (Indirectly via Mongoose Models)
- Pattern: Repository
- Implementation:
- Mongoose models (
User.js,Post.js, etc.) act as repositories, abstracting database operations. - Example:
// src/models/User.js import mongoose from 'mongoose'; import bcrypt from 'bcrypt'; const userSchema = new mongoose.Schema({ email: { type: String, required: true, unique: true }, password: { type: String, required: true }, // ... other fields }); userSchema.pre('save', async function (next) { if (!this.isModified('password')) return next(); this.password = await bcrypt.hash(this.password, 10); next(); }); export default mongoose.model('User', userSchema); - Why?
- Decouples business logic from database schema.
- Provides a consistent interface for CRUD operations.
- Mongoose models (
1.2.4. Strategy Pattern (Authentication Providers)
- Pattern: Strategy
- Implementation:
- Multiple authentication strategies (Local, Google OAuth) are implemented as separate strategies and selected dynamically.
- Example:
// src/config/passport.js import { Strategy as GoogleStrategy } from 'passport-google-oauth20'; import passport from 'passport'; import User from '../models/User.js'; passport.use( new GoogleStrategy( { clientID: process.env.GOOGLE_CLIENT_ID, clientSecret: process.env.GOOGLE_CLIENT_SECRET, callbackURL: process.env.GOOGLE_CALLBACK_URL, }, async (accessToken, refreshToken, profile, done) => { // Strategy-specific logic (e.g., Google OAuth) const user = await User.findOne({ googleId: profile.id }); if (user) return done(null, user); // ... create new user } ) ); - Why?
- Allows extensibility (e.g., adding GitHub OAuth later).
- Keeps authentication logic modular.
1.2.5. Observer Pattern (Real-Time Updates via Socket.IO)
- Pattern: Observer (Pub/Sub)
- Implementation:
socket.jssets up a WebSocket server that listens for events (e.g., new post, comment) and broadcasts updates to connected clients.- Example:
// src/socket/socket.js import { Server } from 'socket.io'; export const setupSocket = (server) => { const io = new Server(server, { cors: { origin: process.env.CLIENT_URL }, }); io.on('connection', (socket) => { console.log('New client connected:', socket.id); socket.on('joinRoom', (userId) => { socket.join(userId); // Join a room for the user }); // Broadcast new post to followers socket.on('newPost', (post) => { io.to(post.authorId).emit('postCreated', post); }); }); }; - Why?
- Enables real-time features (notifications, live feeds).
- Decouples real-time logic from HTTP controllers.
1.2.6. Decorator Pattern (API Response Wrappers)
- Pattern: Decorator
- Implementation:
apiResponse.jswraps API responses in a consistent format (success/error).- Example:
// src/utils/apiResponse.js export const successResponse = (res, data, status = 200) => { res.status(status).json({ success: true, data, }); }; export const errorResponse = (res, error, status = 400) => { res.status(status).json({ success: false, message: error.message || 'Something went wrong', }); }; - Why?
- Ensures consistent API responses across all endpoints.
- Reduces boilerplate in controllers.
1.3. Module Interactions & Data Flow
1.3.1. Request Lifecycle
- Request Ingress:
- HTTP request enters via
server.jsβapp.jsβ middleware pipeline.
- HTTP request enters via
- Authentication & Authorization:
auth.middleware.jsvalidates JWT (if present) and attaches the user toreq.user.admin.middleware.jschecks roles (e.g.,req.user.role === 'admin').
- Validation:
validate.middleware.jsusesexpress-validatorto validate request bodies/params.
- Controller Execution:
- Route handler (e.g.,
post.controller.js) processes the request, interacts with models, and returns a response.
- Route handler (e.g.,
- Response Egress:
- Response is formatted via
apiResponse.jsand sent back to the client.
- Response is formatted via
- Real-Time Updates (Optional):
- If the action triggers a real-time event (e.g., new post),
socket.jsbroadcasts it to connected clients.
- If the action triggers a real-time event (e.g., new post),
1.3.2. Key Interactions
| Source | Target | Interaction |
|---|---|---|
server.js | app.js | Initializes Express app and starts HTTP server. |
app.js | auth.middleware.js | Attaches authentication middleware to all routes. |
auth.controller.js | User model | Validates credentials and generates JWT tokens. |
post.controller.js | Post model | Creates/updates posts; emits newPost event via socket.js. |
upload.middleware.js | cloudinary.js | Uploads files to Cloudinary; returns URL for storage in DB. |
notification.controller.js | Notification model | Creates notifications; triggers sendPushNotification.js for WebPush. |
1.4. Advanced Concerns
1.4.1. Security
- JWT Authentication:
- Short-lived access tokens (
15m) + long-lived refresh tokens (7d). - Refresh tokens are stored in HTTP-only cookies.
- Short-lived access tokens (
- Rate Limiting:
express-rate-limitprotects against brute-force attacks.
- Helmet & CORS:
helmetsets secure HTTP headers.- CORS restricted to
CLIENT_URL.
- Input Sanitization:
express-validatorsanitizes user input to prevent XSS/SQLi.
1.4.2. Scalability
- Database:
- MongoDB Atlas (scalable cloud DB).
- File Storage:
- Cloudinary (scalable CDN for images/videos).
- Real-Time:
- Socket.IO with Redis adapter (not shown, but implied for multi-server setups).
1.4.3. Error Handling
- Centralized Error Middleware:
- Uncaught errors are caught and formatted via
errorResponse.
- Uncaught errors are caught and formatted via
- Mongoose Validation:
- Schema-level validation (e.g.,
required,unique).
- Schema-level validation (e.g.,
1.4.4. Environment Management
.env.example:- Documents required environment variables.
envValidator.js:- Validates
.envat startup (not shown in file tree, but implied).
- Validates
2. Data Flow & State Transitions
| Origin | Action | Logic Handler | Resulting State |
|---|---|---|---|
| Client | Send HTTP Request | server.js β app.js | Request enters middleware pipeline. |
| Middleware Pipeline | Authenticate (JWT) | auth.middleware.js | req.user attached if valid; otherwise, 401 Unauthorized. |
| Middleware Pipeline | Validate Request | validate.middleware.js | Request body/params validated; errors returned if invalid. |
| Controller | Process Business Logic | post.controller.js | Calls Post.create(); emits newPost event via socket.js. |
| Model | Save to Database | Post.js | Post document created in MongoDB. |
| Cloudinary | Upload Media | upload.middleware.js β cloudinary.js | File uploaded; URL stored in Post.mediaUrl. |
| Socket.IO | Broadcast Real-Time Event | socket.js | Connected clients receive postCreated event. |
| Nodemailer | Send Email (e.g., verification) | sendEmail.js | Email sent to user; state updated to emailVerified: true. |
| WebPush | Send Push Notification | sendPushNotification.js | Notification delivered to userβs device. |
| Admin Middleware | Check Admin Role | admin.middleware.js | Request proceeds if req.user.role === 'admin'; otherwise, 403 Forbidden. |
3. Mermaid.js Architecture Diagram
4. Summary of Key Takeaways
-
Modular & Layered Design:
- Clear separation of concerns (config, models, controllers, routes, middlewares).
- Follows MVC with additional real-time and utility layers.
-
Design Patterns:
- Middleware Chain (Express.js).
- Repository (Mongoose models).
- Strategy (Authentication providers).
- Observer (Socket.IO).
- Decorator (API response wrappers).
-
Scalability & Security:
- JWT + refresh tokens for auth.
- Rate limiting, CORS, Helmet for security.
- Cloudinary/Mux for scalable media handling.
-
Real-Time Capabilities:
- Socket.IO for live updates (posts, notifications).
-
Extensibility:
- Easy to add new routes, middlewares, or authentication strategies.
This architecture is well-structured for a social media backend, balancing modularity, scalability, and real-time functionality.
π System Architecture Diagram
π οΈ 4. Function Breakdowns
Analysis of Provided Source Files
The provided source files are mostly configuration files and do not contain actual code. However, we can still analyze the content of these files to understand the project structure and dependencies.
.env.example
This file contains environment variables used by the application. The following table summarizes the key variables:
| Function/Export Name | Parameters | Logic Description | Impact |
|---|---|---|---|
| PORT | 5000 | Sets the port number for the application | Defines the port used by the application to listen for incoming requests |
| NODE_ENV | development | Sets the environment mode for the application | Defines the environment mode, which can affect logging, debugging, and other behaviors |
| MONGO_URI | mongodb+srv://<user>:<pass>@cluster.mongodb.net/sob | Sets the connection string for the MongoDB database | Defines the connection settings for the MongoDB database |
| JWT_ACCESS_SECRET | your_jwt_access_secret_here | Sets the secret key for access tokens | Defines the secret key used to sign and verify access tokens |
| JWT_REFRESH_SECRET | your_jwt_refresh_secret_here | Sets the secret key for refresh tokens | Defines the secret key used to sign and verify refresh tokens |
| JWT_ACCESS_EXPIRES | 15m | Sets the expiration time for access tokens | Defines the duration for which access tokens are valid |
| JWT_REFRESH_EXPIRES | 7d | Sets the expiration time for refresh tokens | Defines the duration for which refresh tokens are valid |
| GOOGLE_CLIENT_ID | your_google_client_id_here | Sets the client ID for Google OAuth | Defines the client ID used for Google OAuth authentication |
| GOOGLE_CLIENT_SECRET | your_google_client_secret_here | Sets the client secret for Google OAuth | Defines the client secret used for Google OAuth authentication |
| GOOGLE_CALLBACK_URL | http://localhost:5000/api/auth/google/callback | Sets the callback URL for Google OAuth | Defines the URL to which the user is redirected after Google OAuth authentication |
| CLOUDINARY_CLOUD_NAME | your_cloudinary_cloud_name_here | Sets the cloud name for Cloudinary | Defines the cloud name used for Cloudinary integration |
| CLOUDINARY_API_KEY | your_cloudinary_api_key_here | Sets the API key for Cloudinary | Defines the API key used for Cloudinary integration |
| CLOUDINARY_API_SECRET | your_cloudinary_api_secret_here | Sets the API secret for Cloudinary | Defines the API secret used for Cloudinary integration |
| MAIL_USER | your_email@gmail.com | Sets the email address used for sending emails | Defines the email address used for sending emails |
| MAIL_PASS | your_email_app_password_here | Sets the password for the email address | Defines the password used for sending emails |
| CLIENT_URL | http://localhost:3000 | Sets the URL for the client application | Defines the URL used for CORS and OAuth redirect |
jsconfig.json
This file contains configuration settings for JavaScript compilation. The following table summarizes the key settings:
| Function/Export Name | Parameters | Logic Description | Impact |
|---|---|---|---|
| compilerOptions.module | ESNext | Sets the module system used by the compiler | Defines the module system used by the application |
| compilerOptions.target | ES2020 | Sets the target JavaScript version for the compiler | Defines the target JavaScript version for the application |
| compilerOptions.checkJs | false | Disables type checking for JavaScript files | Disables type checking for JavaScript files |
| compilerOptions.moduleResolution | bundler | Sets the module resolution strategy used by the compiler | Defines the module resolution strategy used by the application |
| include | src/**/*.js, server.js | Specifies the files and directories to include in the compilation | Defines the files and directories to include in the compilation |
| exclude | node_modules | Specifies the files and directories to exclude from the compilation | Defines the files and directories to exclude from the compilation |
package-lock.json
This file contains a snapshot of the dependencies and their versions used by the application. The following table summarizes the key dependencies:
| Function/Export Name | Parameters | Logic Description | Impact |
|---|---|---|---|
| @mux/mux-node | ^14.1.1 | Sets the version range for the @mux/mux-node dependency | Defines the version range for the @mux/mux-node dependency |
| bcrypt | ^6.0.0 | Sets the version range for the bcrypt dependency | Defines the version range for the bcrypt dependency |
| cloudinary | ^2.10.0 | Sets the version range for the cloudinary dependency | Defines the version range for the cloudinary dependency |
| compression | ^1.8.1 | Sets the version range for the compression dependency | Defines the version range for the compression dependency |
| cors | ^2.8.6 | Sets the version range for the cors dependency | Defines the version range for the cors dependency |
| dotenv | ^17.4.2 | Sets the version range for the dotenv dependency | Defines the version range for the dotenv dependency |
| express | ^5.2.1 | Sets the version range for the express dependency | Defines the version range for the express dependency |
| express-rate-limit | ^8.5.2 | Sets the version range for the express-rate-limit dependency | Defines the version range for the express-rate-limit dependency |
| express-validator | ^7.3.2 | Sets the version range for the express-validator dependency | Defines the version range for the express-validator dependency |
| helmet | ^8.2.0 | Sets the version range for the helmet dependency | Defines the version range for the helmet dependency |
| jsonwebtoken | ^9.0.3 | Sets the version range for the jsonwebtoken dependency | Defines the version range for the jsonwebtoken dependency |
| mongoose | ^9.6.3 | Sets the version range for the mongoose dependency | Defines the version range for the mongoose dependency |
| morgan | ^1.11.0 | Sets the version range for the morgan dependency | Defines the version range for the morgan dependency |
| multer | ^2.1.1 | Sets the version range for the multer dependency | Defines the version range for the multer dependency |
| nodemailer | ^8.0.10 | Sets the version range for the nodemailer dependency | Defines the version range for the nodemailer dependency |
| passport | ^0.7.0 | Sets the version range for the passport dependency | Defines the version range for the passport dependency |
| passport-google-oauth20 | ^2.0.0 | Sets the version range for the passport-google-oauth20 dependency | Defines the version range for the passport-google-oauth20 dependency |
| socket.io | ^4.8.3 | Sets the version range for the socket.io dependency | Defines the version range for the socket.io dependency |
| web-push | ^3.6.7 | Sets the version range for the web-push dependency | Defines the version range for the web-push dependency |
| Note that this is not an exhaustive list of all dependencies, but it covers the key ones. |