Steps to Setup the Backend of Application
Step 1: Create a new directory named backend.
mkdir server
cd server
Step 2: Create a server using the following command in your terminal.
npm init -y
Step 3: Install the necessary package in your server using the following command.
npm install bcryptjs cors dotenv express
npm install cookie-parser jsonwebtoken
npm install mongodb mongoose morgan helmet nodemon
Step 4: Create a .env file to store things you don’t want to show to others.
MONGO = Mention Yours
JWT = jbckjbwd3487238dsnbfkj
Project Structure:
The updated Dependencies in package.json file of backend will look like:
"dependencies": {
"bcryptjs": "^2.4.3",
"cors": "^2.8.5",
"dotenv": "^16.4.4",
"express": "^4.18.2",
"cookie-parser": "^1.4.6",
"jsonwebtoken": "^9.0.2",
"mongodb": "^6.3.0",
"mongoose": "^8.1.3",
"morgan": "^1.10.0",
"helmet": "^7.1.0",
"nodemon": "^3.0.3"
}
Example: Create the required files as shown in folder structure and add the following codes.
// index.js
import express from "express";
import dotenv from "dotenv";
import helmet from "helmet";
import morgan from "morgan";
import mongoose from "mongoose";
import userRoute from "./routes/user.js";
import customerRoute from "./routes/customer.js";
import cookieParser from "cookie-parser";
import cors from "cors"
const app = express();
dotenv.config();
const PORT = process.env.PORT || 7700;
const connect = async () => {
try {
await mongoose.connect(process.env.MONGO);
console.log("Connected to mongoDB.");
} catch (error) {
throw error;
}
};
mongoose.connection.on("disconnected", () => {
console.log("mongoDB disconnected!");
});
app.get('/',
(req, res) => { res.send('Hello from Express!') });
//middlewares
app.use(cookieParser())
app.use(express.json());
app.use(helmet());
app.use(cors({
origin: "http://localhost:3000",
credentials: true
}))
app.use(morgan("common"));
app.use("/api/users", userRoute);
app.use("/api/customers", customerRoute);
app.listen(PORT, () => {
console.log("Listening on port 7700");
connect();
});
// error.js
export const createError = (status, message) => {
const err = new Error();
err.status = status;
err.message = message;
return err;
};
// /server/models/User.js
import mongoose from "mongoose"
const UserSchema = new mongoose.Schema(
{
username: {type: String, required: true, unique: true},
password: {type: String, required: true},
email: { type: String, required: true}
},
{
timestamps: true
}
)
export default mongoose.model("User", UserSchema);
// models/Customer.js
import mongoose from "mongoose";
const CustomerSchema = new mongoose.Schema({
name: { type: String, required: true },
company: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User'
},
service: { type: String, required: true },
email: { type: String, required: true },
phone: { type: String, required: true },
status: { type: String, default: "not started" },
}, {
timestamps: true
})
export default mongoose.model("Customer", CustomerSchema);
// controllers/user.js
import User from "../models/User.js";
import bcrypt from "bcryptjs";
import { createError } from "../error.js";
import jwt from "jsonwebtoken";
export const register = async (req, res, next) => {
try {
//check for already exist
const em = await User.findOne({ email: req.body.email });
if (em)
return res.status(409).send({
message: "User with given email already exists"
})
const salt = bcrypt.genSaltSync(10);
const hash = bcrypt.hashSync(req.body.password, salt);
const newUser = new User({
...req.body,
password: hash,
});
await newUser.save();
res.status(200).send("User has been created.");
} catch (err) {
next(err);
}
};
export const login = async (req, res, next) => {
try {
const user = await User.findOne({
username: req.body.username
});
if (!user) return next(
createError(404, "User not found!"));
const isPasswordCorrect = await bcrypt.compare(
req.body.password,
user.password
);
if (!isPasswordCorrect)
return next(createError(
400, "Wrong password or username!"));
const token = jwt.sign(
{ id: user._id, isAdmin: user.isAdmin },
process.env.JWT
);
const { password, isAdmin, ...otherDetails } = user._doc;
res
.cookie("access_token", token, {
httpOnly: true,
})
.status(200)
.json({ details: { ...otherDetails }, isAdmin });
} catch (err) {
next(err);
}
};
// controllers/customer.js
import Customer from "../models/Customer.js";
export const createCustomer = async (req, res, next) => {
const newCustomer = new Customer(req.body)
try {
const savedCustomer = await newCustomer.save();
res.status(200).json(savedCustomer);
}
catch (err) {
next(err)
}
}
export const deleteCustomer = async (req, res, next) => {
try {
await Customer.findByIdAndDelete(req.params.id);
res.status(200).json("the Customer has been deleted");
} catch (err) {
next(err);
}
};
export const getCustomers = async (req, res, next) => {
const userId = req.params.userId;
try {
const customers = await Customer.find({ company: userId });
res.status(200).json(customers);
} catch (err) {
next(err)
}
}
export const updateCustomer = async (req, res, next) => {
try {
const customer = await Customer.findByIdAndUpdate(
req.params.id,
{ $set: req.body },
{ new: true }
);
res.status(200).json(customer);
} catch (err) {
next(err);
}
}
// routes/user.js
import express from "express";
import { login, register } from "../controllers/user.js";
const router = express.Router();
router.post("/register", register)
router.post("/login", login)
export default router;
// routes/customer.js
import express from "express";
import {
createCustomer,
deleteCustomer,
getCustomers,
updateCustomer,
} from "../controllers/customer.js";
const router = express.Router();
router.post("/", createCustomer);
router.put("/:id", updateCustomer);
router.delete("/:id", deleteCustomer);
router.get("/:userId", getCustomers);
export default router;
Step 6: To start the backend run the following command.
nodemon index.js
Customer Relationship Management (CRM) System with Node.js and Express.js
CRM systems are important tools for businesses to manage their customer interactions, both with existing and potential clients. In this article, we will demonstrate how to create a CRM system using Node.js and Express. We will cover the key functionalities, prerequisites, approach, and steps required to create the project.
Output Preview: