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?