Advanced Node.js Practical Exam (3 Hours)

 Perfect 👍 Let’s design a realistic advanced-level Node.js practical exam (like a company could give you for a 3-hour take-home or live test).

This exam combines JWT auth, RBAC, file upload, pagination, and real-time notifications → advanced but doable.


📝 Advanced Node.js Practical Exam (3 Hours)

❓ Task

Build a mini backend for an E-commerce system with the following features:

1. Authentication + RBAC

  • Users can register & login (with JWT).

  • Roles: admin, customer.

  • admin → can manage products (create, update, delete).

  • customer → can view products only.

2. Product Management API

  • POST /products (admin only) → create product (name, price, image).

  • GET /products (all users) → paginated & searchable product list.

    • Example: /products?page=2&limit=5&search=phone

  • PUT /products/:id (admin only) → update product.

  • DELETE /products/:id (admin only).

3. File Upload

  • Product must support image upload (use multer).

  • Store image locally (or AWS S3 if you want bonus).

4. Real-Time Notifications

  • When a new product is added by admin → notify all connected users in real time (via Socket.IO).

5. Bonus (if time remains)

  • Add refresh tokens for login.

  • Add rate limiting (max 100 requests per 15 min per IP).


✅ Solution Outline

1. Setup

npm init -y
npm install express bcryptjs jsonwebtoken sequelize pg passport passport-jwt multer socket.io cors dotenv express-rate-limit

2. Models

User

// models/User.js
const { DataTypes } = require("sequelize");
const sequelize = require("../db");

const User = sequelize.define("User", {
  name: DataTypes.STRING,
  email: { type: DataTypes.STRING, unique: true },
  password: DataTypes.STRING,
  role: { type: DataTypes.STRING, defaultValue: "customer" }
});

module.exports = User;

Product

// models/Product.js
const { DataTypes } = require("sequelize");
const sequelize = require("../db");

const Product = sequelize.define("Product", {
  name: DataTypes.STRING,
  price: DataTypes.FLOAT,
  image: DataTypes.STRING
});

module.exports = Product;

3. Middleware

Auth (JWT + Role Check)

const jwt = require("jsonwebtoken");

function auth(role = null) {
  return (req, res, next) => {
    const token = req.headers["authorization"];
    if (!token) return res.status(401).json({ message: "No token" });

    jwt.verify(token.split(" ")[1], process.env.JWT_SECRET, (err, decoded) => {
      if (err) return res.status(401).json({ message: "Invalid token" });
      req.user = decoded;
      if (role && decoded.role !== role) {
        return res.status(403).json({ message: "Forbidden" });
      }
      next();
    });
  };
}

module.exports = auth;

4. Routes

Auth Routes

  • POST /register → create user (default role = customer).

  • POST /login → return JWT.

Product Routes

  • POST /products → admin only (upload image).

  • GET /products → all users, with pagination + search.

  • PUT /products/:id → admin only.

  • DELETE /products/:id → admin only.


5. File Upload

const multer = require("multer");
const path = require("path");

const storage = multer.diskStorage({
  destination: "uploads/",
  filename: (req, file, cb) => {
    cb(null, Date.now() + path.extname(file.originalname));
  },
});

const upload = multer({ storage });

Use in route:

router.post("/products", auth("admin"), upload.single("image"), async (req, res) => {
  const product = await Product.create({
    name: req.body.name,
    price: req.body.price,
    image: req.file.filename,
  });
  io.emit("newProduct", product); // notify all users in real-time
  res.json(product);
});

6. Real-Time Notifications

In index.js:

const express = require("express");
const http = require("http");
const { Server } = require("socket.io");
const cors = require("cors");

const app = express();
const server = http.createServer(app);
const io = new Server(server, { cors: { origin: "*" } });

global.io = io; // make io available globally

io.on("connection", (socket) => {
  console.log("User connected:", socket.id);
});

7. Pagination + Search

router.get("/products", auth(), async (req, res) => {
  const { page = 1, limit = 10, search = "" } = req.query;
  const offset = (page - 1) * limit;

  const products = await Product.findAndCountAll({
    where: { name: { [Op.iLike]: `%${search}%` } },
    limit: parseInt(limit),
    offset,
  });

  res.json({
    total: products.count,
    page,
    pages: Math.ceil(products.count / limit),
    data: products.rows,
  });
});

8. Rate Limiting (Bonus)

const rateLimit = require("express-rate-limit");

const limiter = rateLimit({
  windowMs: 15 * 60 * 1000,
  max: 100,
});

app.use(limiter);

🎯 What This Exam Covers

  • JWT Authentication ✅

  • Role-Based Access Control (RBAC) ✅

  • File Uploads (multer) ✅

  • Pagination + Search ✅

  • Real-Time Notifications (Socket.IO) ✅

  • Security: Rate limiting ✅

This is exactly the kind of advanced-level practical exam companies love, because it mimics real backend work.


👉 Do you want me to build a complete ready-to-run project repo (all files) so you can clone and practice, or just keep it as structured outline + snippets?

Previous Post Next Post