Merged backend from Salvi

This commit is contained in:
2025-02-22 20:19:36 +05:30
26 changed files with 3803 additions and 0 deletions
+57
View File
@@ -0,0 +1,57 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Dependency directories
node_modules/
jspm_packages/
# Environment files
.env
.env.*.local
# Build outputs
dist/
build/
# Static files
public/
out/
# Test files
coverage/
*.lcov
# Database files
*.sqlite3
*.db
*.db-wal
*.db-shm
# Temporary files
*.tmp
*.temp
*.swp
*.swo
# IDE and editor files
.vscode/
.idea/
*.iml
# System files
.DS_Store
Thumbs.db
# Other
*.log.*
+156
View File
@@ -0,0 +1,156 @@
const Crop = require("../Models/crop.model.js");
const Farm = require("../Models/farm.model.js");
const { uploadOnCloudinary } = require("../Utils/cloudinary.js");
// Create a new crop
const createCrop = async (req, res) => {
try {
const { name, farm, harvestDate, growthStage, healthStatus } = req.body;
if (!req.file.path) {
res.status(500).json({
success: false,
message: "Avatar not uploaded on cloudinary.",
});
}
const imageUrl = await uploadOnCloudinary(req.file.path);
console.log("Image url is : ", imageUrl);
if (!imageUrl) {
return res.status(500).json({
success: false,
message: "Image not uploaded on cloudinary.",
});
}
// Check if the farm exists
const existingFarm = await Farm.findById(farm);
if (!existingFarm)
return res.status(404).json({ message: "Farm not found" });
const crop = new Crop({
name,
farm,
image: imageUrl,
harvestDate,
growthStage,
healthStatus,
});
await crop.save();
// Add crop to farm
existingFarm.crops.push(crop._id);
await existingFarm.save();
res.status(201).json(crop);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Get all crops for a specific farm
const getCropsByFarm = async (req, res) => {
try {
console.log("My farm id is : ", req.params.farmId);
const crops = await Crop.find({ farm: req.params.farmId });
res.status(200).json(crops);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Get a single crop by ID
const getCropById = async (req, res) => {
try {
const crop = await Crop.findById(req.params.cropId).populate("farm");
if (!crop) return res.status(404).json({ message: "Crop not found" });
res.status(200).json(crop);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Update crop details
const updateCrop = async (req, res) => {
try {
const updatedCrop = await Crop.findByIdAndUpdate(
req.params.cropId,
req.body,
{ new: true }
);
if (!updatedCrop)
return res.status(404).json({ message: "Crop not found" });
res.status(200).json(updatedCrop);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Delete a crop
const deleteCrop = async (req, res) => {
try {
const crop = await Crop.findById(req.params.cropId);
if (!crop) return res.status(404).json({ message: "Crop not found" });
await crop.deleteOne();
// Remove crop from the farm
await Farm.findByIdAndUpdate(crop.farm, { $pull: { crops: crop._id } });
res.status(200).json({ message: "Crop deleted successfully" });
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Update crop growth stage
const updateGrowthStage = async (req, res) => {
try {
const { growthStage } = req.body;
const crop = await Crop.findById(req.params.cropId);
if (!crop) return res.status(404).json({ message: "Crop not found" });
crop.growthStage = growthStage;
await crop.save();
res.status(200).json({ message: "Growth stage updated", crop });
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Update crop health status
const updateHealthStatus = async (req, res) => {
try {
const { healthStatus } = req.body;
const crop = await Crop.findById(req.params.cropId);
if (!crop) return res.status(404).json({ message: "Crop not found" });
crop.healthStatus = healthStatus;
await crop.save();
res.status(200).json({ message: "Health status updated", crop });
} catch (error) {
res.status(500).json({ message: error.message });
}
};
module.exports = {
createCrop,
getCropsByFarm,
getCropById,
updateCrop,
deleteCrop,
updateGrowthStage,
updateHealthStatus,
};
+130
View File
@@ -0,0 +1,130 @@
const Farm = require("../Models/farm.model.js");
const Crop = require("../Models/crop.model.js");
const Finance = require("../Models/finance.model.js");
// Create a farm
const createFarm = async (req, res) => {
try {
const { name, location, waterContent, soilType } = req.body;
const farm = new Farm({
name,
location,
waterContent,
soilType,
owner: req.user._id,
});
await farm.save();
res.status(201).json(farm);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Get all farms for a user
const getUserFarms = async (req, res) => {
try {
const farms = await Farm.find({ owner: req.user._id })
.populate("crops")
.populate("finances");
res.status(200).json(farms);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Get a single farm by ID
const getFarmById = async (req, res) => {
try {
const farm = await Farm.findById(req.params.farmId)
.populate("crops")
.populate("finances");
if (!farm) return res.status(404).json({ message: "Farm not found" });
res.status(200).json(farm);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Update farm details
const updateFarm = async (req, res) => {
try {
const updatedFarm = await Farm.findByIdAndUpdate(
req.params.farmId,
req.body,
{ new: true }
);
if (!updatedFarm)
return res.status(404).json({ message: "Farm not found" });
res.status(200).json(updatedFarm);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Delete a farm
const deleteFarm = async (req, res) => {
try {
const farm = await Farm.findById(req.params.farmId);
if (!farm) return res.status(404).json({ message: "Farm not found" });
await Crop.deleteMany({ farm: farm._id });
await Finance.findByIdAndDelete(farm.finances);
await farm.deleteOne();
res.status(200).json({ message: "Farm deleted successfully" });
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Add fertilizer to a farm
const addFertilizer = async (req, res) => {
try {
const { name, quantity } = req.body;
const farm = await Farm.findById(req.params.farmId);
if (!farm) return res.status(404).json({ message: "Farm not found" });
farm.fertilizer.push({ name, quantity });
await farm.save();
res.status(200).json({ message: "Fertilizer added", farm });
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Add pesticide to a farm
const addPesticide = async (req, res) => {
try {
const { name, quantity } = req.body;
const farm = await Farm.findById(req.params.farmId);
if (!farm) return res.status(404).json({ message: "Farm not found" });
farm.pestisides.push({ name, quantity });
await farm.save();
res.status(200).json({ message: "Pesticide added", farm });
} catch (error) {
res.status(500).json({ message: error.message });
}
};
module.exports = {
createFarm,
getUserFarms,
getFarmById,
updateFarm,
deleteFarm,
addFertilizer,
addPesticide,
};
+126
View File
@@ -0,0 +1,126 @@
import Finance from "../models/financeModel.js";
import Farm from "../models/farmModel.js";
// Create finance record for a farm
export const createFinance = async (req, res) => {
try {
const { farm } = req.body;
// Check if the farm exists
const existingFarm = await Farm.findById(farm);
if (!existingFarm)
return res.status(404).json({ message: "Farm not found" });
const finance = new Finance({
farm,
transactions: [],
totalExpenses: 0,
totalRevenue: 0,
});
await finance.save();
// Link finance to farm
existingFarm.finances = finance._id;
await existingFarm.save();
res.status(201).json(finance);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Get finance details by farm ID
export const getFinanceByFarm = async (req, res) => {
try {
const finance = await Finance.findOne({ farm: req.params.farmId });
if (!finance)
return res.status(404).json({ message: "Finance record not found" });
res.status(200).json(finance);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Add a transaction (expense/revenue)
export const addTransaction = async (req, res) => {
try {
const { type, amount, description } = req.body;
const finance = await Finance.findById(req.params.financeId);
if (!finance)
return res.status(404).json({ message: "Finance record not found" });
finance.transactions.push({ type, amount, description });
// Update totals
if (type === "Expense") {
finance.totalExpenses += amount;
} else if (type === "Revenue") {
finance.totalRevenue += amount;
}
await finance.save();
res.status(200).json({ message: "Transaction added", finance });
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Delete a transaction
export const deleteTransaction = async (req, res) => {
try {
const finance = await Finance.findById(req.params.financeId);
if (!finance)
return res.status(404).json({ message: "Finance record not found" });
const transaction = finance.transactions.id(req.params.transactionId);
if (!transaction)
return res.status(404).json({ message: "Transaction not found" });
// Adjust totals before removing
if (transaction.type === "Expense") {
finance.totalExpenses -= transaction.amount;
} else if (transaction.type === "Revenue") {
finance.totalRevenue -= transaction.amount;
}
transaction.remove();
await finance.save();
res.status(200).json({ message: "Transaction deleted", finance });
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Get all transactions for a farm's finance
export const getTransactions = async (req, res) => {
try {
const finance = await Finance.findById(req.params.financeId);
if (!finance)
return res.status(404).json({ message: "Finance record not found" });
res.status(200).json(finance.transactions);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Get total expenses and revenue
export const getFinancialSummary = async (req, res) => {
try {
const finance = await Finance.findById(req.params.financeId);
if (!finance)
return res.status(404).json({ message: "Finance record not found" });
res.status(200).json({
totalExpenses: finance.totalExpenses,
totalRevenue: finance.totalRevenue,
});
} catch (error) {
res.status(500).json({ message: error.message });
}
};
+111
View File
@@ -0,0 +1,111 @@
import Task from "../models/taskModel.js";
import Farm from "../models/farmModel.js";
import Crop from "../models/cropModel.js";
// Create a new task
export const createTask = async (req, res) => {
try {
const { farm, crop, taskType, description, assignedDate, status } =
req.body;
// Validate farm existence
const existingFarm = await Farm.findById(farm);
if (!existingFarm)
return res.status(404).json({ message: "Farm not found" });
// Validate crop if provided
if (crop) {
const existingCrop = await Crop.findById(crop);
if (!existingCrop)
return res.status(404).json({ message: "Crop not found" });
}
const task = new Task({
farm,
crop,
taskType,
description,
assignedDate,
status,
});
await task.save();
res.status(201).json(task);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Get all tasks for a specific farm
export const getTasksByFarm = async (req, res) => {
try {
const tasks = await Task.find({ farm: req.params.farmId }).populate("crop");
res.status(200).json(tasks);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Get a single task by ID
export const getTaskById = async (req, res) => {
try {
const task = await Task.findById(req.params.taskId).populate("farm crop");
if (!task) return res.status(404).json({ message: "Task not found" });
res.status(200).json(task);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Update task details
export const updateTask = async (req, res) => {
try {
const updatedTask = await Task.findByIdAndUpdate(
req.params.taskId,
req.body,
{ new: true }
);
if (!updatedTask)
return res.status(404).json({ message: "Task not found" });
res.status(200).json(updatedTask);
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Delete a task
export const deleteTask = async (req, res) => {
try {
const task = await Task.findById(req.params.taskId);
if (!task) return res.status(404).json({ message: "Task not found" });
await task.deleteOne();
res.status(200).json({ message: "Task deleted successfully" });
} catch (error) {
res.status(500).json({ message: error.message });
}
};
// Update task status (Pending → Completed)
export const updateTaskStatus = async (req, res) => {
try {
const { status } = req.body;
const task = await Task.findById(req.params.taskId);
if (!task) return res.status(404).json({ message: "Task not found" });
task.status = status;
await task.save();
res.status(200).json({ message: "Task status updated", task });
} catch (error) {
res.status(500).json({ message: error.message });
}
};
+466
View File
@@ -0,0 +1,466 @@
const catchAsyncErrors = require("../Middlewares/catchAsyncErrors.js");
const User = require("../Models/user.model.js");
const { uploadOnCloudinary } = require("../Utils/cloudinary.js");
const sendEmail = require("../Utils/sendmail.js");
const crypto = require("crypto");
const jwt = require("jsonwebtoken");
// Register or Sign up new User -- Done
const registerUser = catchAsyncErrors(async (req, res) => {
const { name, email, password, role } = req.body;
const user = await User.create({
name,
email,
password,
role,
});
if (!user) {
return res.status(500).json({
success: false,
message: "User not created something went wrong.",
});
}
return res.status(200).json({
success: true,
message: "User is registered successfully",
data: user,
});
});
// Login user in our web app -- Done
const loginUser = catchAsyncErrors(async (req, res) => {
const { email, password } = req.body;
const user = await User.findOne({ email });
if (!user) {
return res.status(404).json({
success: false,
message: "User not found",
});
}
const checkUser = await user.isPasswordCorrect(password);
if (!checkUser) {
return res.status(500).json({
success: false,
message: "Password is incorrect",
});
}
const token = await user.generateRefreshToken();
if (!token) {
return res.status(500).json({
success: false,
message: "token not created something went wrong.",
});
}
user.password = null;
return res
.status(200)
.cookie(process.env.TOKEN_NAME, token, {
path: "/",
sameSite: "None",
secure: process.env.NODE_ENV === "production",
httpOnly: true,
expires: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
})
.json({
success: true,
message: "User is successfully logged in.",
data: user,
});
});
// Logout user in our web app -- Done
const logoutUser = catchAsyncErrors(async (req, res) => {
return res
.clearCookie(process.env.TOKEN_NAME, {
path: "/",
sameSite: "None",
secure: process.env.NODE_ENV === "production",
httpOnly: true,
expires: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
})
.status(201)
.json({
success: true,
message: "User is logged out successfully",
});
});
// -- DONE
const intializeUser = catchAsyncErrors(async (req, res) => {
const tokenValue = req.cookies[process.env.TOKEN_NAME];
// console.log("I am the one who is doing this : ", tokenValue);
if (!tokenValue) {
return res.status(404).json({
success: false,
message: "User is not logged in.",
});
}
try {
const payload = await jwt.verify(
tokenValue,
process.env.REFRESH_TOKEN_SECRET
);
if (!payload) {
return res.status(404).json({
success: false,
message: "Something went wrong",
});
}
const user = await User.findById(payload._id).select("-password");
return res.status(200).json({
success: true,
message: "User data get successfully",
data: user,
});
} catch (error) {
return res.status(404).json({
success: false,
message: "Something went wrong",
});
}
});
// Update user deatails -- ADMIN
const updateUserDetails = catchAsyncErrors(async (req, res) => {
const user = await User.findById(req.params.id);
if (!user) {
return res.status(404).json({
success: true,
message: "User not found",
});
}
const { name, email } = req.body;
const updateUser = await User.findByIdAndUpdate(req.params.id, {
$set: {
name: name,
email: email,
},
}).select("-password");
return res.status(200).json({
success: true,
message: "User is updated successfully",
data: updateUser,
});
});
// forget password -- Done
const forgetPassword = catchAsyncErrors(async (req, res) => {
const { email } = req.body;
const user = await User.findOne({ email });
if (!user) {
return res.status(404).json({
success: false,
message: "User not found ",
});
}
// get reset password
const resetToken = await user.getResetPassword();
await user.save({ validateBeforeSave: false });
/*const resetPasswordUrl = `${req.protocol}://${req.get(
"host"
)}/api/v1/password/reset/${resetToken}`;*/
const resetPasswordUrl = `${process.env.FRONTEND_URI}/user/api/v1/password/reset/${resetToken}`;
const message = `Your password token is :-\n\n${resetPasswordUrl}\n\nIf you are not requested this email then please ingore this mail.`;
try {
await sendEmail({
email: user.email,
subject: "MentorFlux password recovery",
message: message,
});
return res.status(200).json({
success: true,
message: `Email sent to ${email} successfully`,
});
} catch (error) {
user.resetPasswordToken = undefined;
user.resetPasswordExpiry = undefined;
await user.save({ validateBeforeSave: false });
return res.status(500).json({
success: false,
message: "Something went wrong ",
error: error,
});
}
});
// reset users password -- DONE
const resetPassword = catchAsyncErrors(async (req, res) => {
const token = req.params.token;
const { password, confirmPassword } = req.body;
//console.log("My password is :", password);
//console.log("My confirmPassword is :", confirmPassword);
//console.log("My token is :", token);
const resetPasswordToken = await crypto
.createHash("sha256")
.update(token)
.digest("hex");
const user = await User.findOne({
resetPasswordToken,
resetPasswordExpiry: { $gte: Date.now() },
});
if (!user) {
return res.status(401).json({
success: false,
message: "Reset Password token is invalid or has been expired",
});
}
if (password !== confirmPassword) {
return res.status(401).json({
success: false,
message: "Please enter password and confirm password",
});
}
user.password = password;
user.resetPasswordToken = undefined;
user.resetPasswordExpiry = undefined;
//console.log("To check the user ", user);
await user.save();
return res.status(200).json({
success: true,
message: "Password changed successfully",
});
});
// get user personal details
const getUserDetails = catchAsyncErrors(async (req, res) => {
const user = await User.findById(req.user._id);
if (!user) {
return res.status(500).json({
success: false,
message: "Something went wrong ",
});
}
return res.status(200).json({
success: true,
message: "User details are fetched successfully",
data: user,
});
});
// Update users password
const updatePassword = catchAsyncErrors(async (req, res) => {
const { password, oldPassword, confirmPassword } = req.body;
const user = await User.findById(req.user._id);
const isPasswordMatched = await user.isPasswordCorrect(oldPassword);
if (!user) {
return res.status(500).json({
success: false,
message: "User not found",
});
}
if (!isPasswordMatched) {
return res.status(500).json({
success: false,
message: "Old password is incorrect.Please enter correct password ",
});
}
if (password !== confirmPassword) {
return res.status(500).json({
success: false,
message: "Password and Confirm password should be same.",
});
}
user.password = password;
await user.save({ validateBeforeSave: false });
return res.status(200).json({
success: true,
message: "Password upadated successfully",
});
});
// update personal details
const updatePersonalDetails = catchAsyncErrors(async (req, res) => {
const { name, email } = req.body;
const user = await User.findByIdAndUpdate(req.user._id, {
$set: {
name,
email,
},
});
if (!user) {
return res.status(500).json({
success: false,
message: "Something went wrong",
});
}
return res.status(200).json({
success: true,
message: "User details updated successfully",
data: user,
});
});
// Get all users details -- ADMIN
const getAllusersDetail = catchAsyncErrors(async (req, res) => {
const users = await find();
return res.status(200).json({
success: true,
message: "All user fetch successfully",
data: users,
});
});
// get single user details
const getSingaluserDetail = catchAsyncErrors(async (req, res) => {
const user = await User.findById(req.params.id);
if (!user) {
return res.status(404).json({
success: false,
message: "User not found",
});
}
});
// upadate user Role -- ADMIN
const updateUserRole = catchAsyncErrors(async (req, res) => {
const { name, email, role } = req.body;
const user = await User.findByIdAndUpdate(req.params.id, {
$set: {
name,
email,
role,
},
});
if (!user) {
return res.status(500).json({
success: false,
message: "Something went wrong",
});
}
return res.status(200).json({
success: true,
message: "User Role updated successfully",
data: user,
});
});
// Delete user -- ADMIN
const DeleteUser = catchAsyncErrors(async (req, res) => {
const user = await User.findByIdAndDelete(req.params.id);
if (!user) {
return res.status(404).json({
success: false,
message: "User does not exist",
});
}
return res.status(200).json({
success: true,
message: "User deleted successfully",
data: user,
});
});
// update avatar -- user
const updateAvatar = catchAsyncErrors(async (req, res) => {
//console.log("Our file is : ", req.file.path);
if (!req.file.path) {
res.status(500).json({
success: false,
message: "Avatar not uploaded on cloudinary.",
});
}
const avatarUrl = await uploadOnCloudinary(req.file.path);
if (!avatarUrl) {
return res.status(500).json({
success: false,
message: "Avatar not uploaded on cloudinary.",
});
}
//console.log("Avatar url is : ", avatarUrl);
//console.log("our user is : ", req.user);
const user = await User.findByIdAndUpdate(req.user._id, {
$set: {
avatar: avatarUrl,
},
});
if (!user) {
return res.status(404).json({
success: false,
message: "User not found.",
});
}
return res.status(200).json({
success: true,
message: "Avatar updated successfully.",
data: user,
});
});
module.exports = {
registerUser,
loginUser,
logoutUser,
updateUserDetails,
forgetPassword,
resetPassword,
getUserDetails,
updatePassword,
updatePersonalDetails,
updateUserRole,
DeleteUser,
intializeUser,
updateAvatar,
};
+21
View File
@@ -0,0 +1,21 @@
const mongoose = require("mongoose");
const catchAsyncErrors = require("../Middlewares/catchAsyncErrors.js");
const DB_connect = catchAsyncErrors(async () => {
try {
const connectionInstance = await mongoose.connect(
`${process.env.MONGODB_URI}/${process.env.DATABASE_NAME}`
);
if (!connectionInstance) {
console.log("MongoDB connection failed");
}
console.log(
"MongoDB connected Successfully on server : " +
connectionInstance.connection.host
);
} catch (error) {
console.log("MongoDB connection failed due to some error :", error);
}
});
module.exports = DB_connect;
+49
View File
@@ -0,0 +1,49 @@
const jwt = require("jsonwebtoken");
const User = require("../Models/user.model.js");
const dotenv = require("dotenv");
dotenv.config({
path: "./.env",
});
async function checkAuthenticated(req, res, next) {
const tokenValue = req.cookies[process.env.TOKEN_NAME];
console.log("I am called", tokenValue);
if (!tokenValue) {
return res.status(404).json({
success: false,
message: "User is not logged in.",
});
}
try {
const payload = await jwt.verify(
tokenValue,
process.env.REFRESH_TOKEN_SECRET
);
if (!payload) {
return next();
}
req.user = payload;
return next();
} catch (error) {
return next();
}
}
function authorizeRoles(...roles) {
return async (req, res, next) => {
if (!roles.includes(req.user.role)) {
return res.status(401).json({
success: false,
message: "You are unauthorised to access this resource",
});
return next();
}
return next();
};
}
module.exports = { checkAuthenticated, authorizeRoles };
+3
View File
@@ -0,0 +1,3 @@
module.exports = (theFunc) => (req, res, next) => {
Promise.resolve(theFunc(req, res, next)).catch(next);
};
+16
View File
@@ -0,0 +1,16 @@
const multer = require("multer");
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "./public/images");
},
filename: function (req, file, cb) {
const uniquePrefix = Date.now();
cb(null, uniquePrefix + "-" + file.originalname);
},
});
const upload = multer({ storage: storage });
module.exports = upload;
+22
View File
@@ -0,0 +1,22 @@
const mongoose = require("mongoose");
const cropSchema = new mongoose.Schema(
{
name: { type: String, required: true },
farm: { type: mongoose.Schema.Types.ObjectId, ref: "Farm", required: true },
image: { type: String },
plantedDate: { type: Date, required: true, default: Date.now() },
harvestDate: { type: Date },
growthStage: {
type: String,
enum: ["Planted", "Growing", "Ready to Harvest"],
default: "Planted",
},
healthStatus: { type: String, default: "Healthy" },
},
{ timestamps: true }
);
const Crop = mongoose.model("Crop", cropSchema);
module.exports = Crop;
+36
View File
@@ -0,0 +1,36 @@
const mongoose = require("mongoose");
const farmSchema = new mongoose.Schema(
{
name: { type: String, required: true },
location: { type: String, required: true },
owner: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true,
},
waterContent: { type: String, required: true },
soilType: { type: String, required: true },
fertilizer: [
{
name: { type: String },
quantity: { type: Number },
addedAt: { type: Date, default: Date.now },
},
],
pestisides: [
{
name: { type: String },
quantity: { type: Number },
addedAt: { type: Date, default: Date.now },
},
],
crops: [{ type: mongoose.Schema.Types.ObjectId, ref: "Crop" }],
finances: { type: mongoose.Schema.Types.ObjectId, ref: "Finance" },
},
{ timestamps: true }
);
const Farm = mongoose.model("Farm", farmSchema);
module.exports = Farm;
+21
View File
@@ -0,0 +1,21 @@
const mongoose = require("mongoose");
const financeSchema = new mongoose.Schema(
{
farm: { type: mongoose.Schema.Types.ObjectId, ref: "Farm", required: true },
transactions: [
{
type: { type: String, enum: ["Expense", "Revenue"], required: true },
amount: { type: Number, required: true },
description: { type: String },
date: { type: Date, default: Date.now },
},
],
totalExpenses: { type: Number, default: 0 },
totalRevenue: { type: Number, default: 0 },
},
{ timestamps: true }
);
const Finance = mongoose.model("Finance", financeSchema);
module.exports = Finance;
+31
View File
@@ -0,0 +1,31 @@
const mongoose = require("mongoose");
const taskSchema = new mongoose.Schema(
{
farm: { type: mongoose.Schema.Types.ObjectId, ref: "Farm", required: true },
crop: { type: mongoose.Schema.Types.ObjectId, ref: "Crop" },
taskType: {
type: String,
enum: [
"Sowing",
"Watering",
"Fertilization",
"Pest Control",
"Harvesting",
],
required: true,
},
description: { type: String },
assignedDate: { type: Date, required: true, default: Date.now },
status: {
type: String,
enum: ["Pending", "Completed"],
default: "Pending",
},
},
{ timestamps: true }
);
const Task = mongoose.model("Task", taskSchema);
module.exports = Task;
+85
View File
@@ -0,0 +1,85 @@
const mongoose = require("mongoose");
const bcrypt = require("bcrypt");
const jwt = require("jsonwebtoken");
const crypto = require("crypto");
const userSchema = new mongoose.Schema(
{
name: {
type: String,
required: [true, "Please Enter your name"],
maxLength: [30, "Please Enter the valid name"],
minLength: [2, "Name should have more than 5 characters"],
},
country: {
type: String,
},
email: {
type: String,
required: true,
unique: true,
lowerCase: true,
},
password: {
type: String,
required: true,
minLength: [6, "Password should have more than 6 characters"],
},
avatar: {
type: String,
default: "/images/profile.jpeg",
},
role: { type: String, enum: ["farmer", "admin"], default: "farmer" },
farms: [{ type: mongoose.Schema.Types.ObjectId, ref: "Farm" }],
resetPasswordToken: String,
resetPasswordExpiry: Date,
},
{
timestamps: true,
}
);
userSchema.pre("save", async function (next) {
if (!this.isModified("password")) return next();
this.password = await bcrypt.hash(this.password, 10);
return next();
});
userSchema.methods.isPasswordCorrect = async function (password) {
return await bcrypt.compare(password, this.password);
};
userSchema.methods.generateRefreshToken = async function () {
return await jwt.sign(
{
_id: this._id,
email: this.email,
},
process.env.REFRESH_TOKEN_SECRET
// {
// expiresIn: process.env.REFRESH_TOKEN_EXPIRY,
// }
);
};
userSchema.methods.getResetPassword = async function () {
// Generating token
const resetToken = await crypto.randomBytes(20).toString("hex");
// Hashing and adding reset password token to userschema
this.resetPasswordToken = crypto
.createHash("sha256")
.update(resetToken)
.digest("hex");
this.resetPasswordExpiry = Date.now() + 15 * 60 * 1000;
return resetToken;
};
const User = mongoose.model("User", userSchema);
module.exports = User;
+25
View File
@@ -0,0 +1,25 @@
const express = require("express");
const {
createCrop,
getCropsByFarm,
getCropById,
updateCrop,
deleteCrop,
updateHealthStatus,
updateGrowthStage,
} = require("../Controllers/crop.controller.js");
const { checkAuthenticated } = require("../Middlewares/authentication.js");
const upload = require("../Middlewares/multer.js");
const router = express.Router();
// Routes for crop management
router.post("/", checkAuthenticated, upload.single("image"), createCrop); // Create a new crop
router.get("/farm/:farmId", checkAuthenticated, getCropsByFarm); // Get all crops
router.get("/:cropId", checkAuthenticated, getCropById); // Get a crop by ID
router.put("/:cropId", checkAuthenticated, updateCrop); // Update crop details
router.delete("/:cropId", checkAuthenticated, deleteCrop); // Delete a crop
router.put("/health/:cropId", checkAuthenticated, updateHealthStatus);
router.put("/growth/:cropId", checkAuthenticated, updateGrowthStage);
module.exports = router;
+19
View File
@@ -0,0 +1,19 @@
const express = require("express");
const {
createFarm,
getUserFarms,
getFarmById,
updateFarm,
deleteFarm,
} = require("../Controllers/farm.controller.js");
const { checkAuthenticated } = require("../Middlewares/authentication.js");
const router = express.Router();
router.post("/", checkAuthenticated, createFarm); // Create a new farm
router.get("/", checkAuthenticated, getUserFarms); // Get all farms
router.get("/:farmId", checkAuthenticated, getFarmById); // Get a farm by ID
router.put("/:farmId", checkAuthenticated, updateFarm); // Update a farm
router.delete("/:farmId", checkAuthenticated, deleteFarm); // Delete a farm
module.exports = router;
+24
View File
@@ -0,0 +1,24 @@
import express from "express";
import {
createFinanceRecord,
getFinanceRecords,
getFinanceById,
updateFinance,
deleteFinance,
addTransaction,
} from "../controllers/financeController.js";
import { checkAuthenticated } from "../Middlewares/authentication.js";
const router = express.Router();
// Routes for finance management
router.post("/", checkAuthenticated, createFinanceRecord); // Create a new finance record
router.get("/", checkAuthenticated, getFinanceRecords); // Get all finance records
router.get("/:financeId", checkAuthenticated, getFinanceById); // Get a finance record by ID
router.put("/:financeId", checkAuthenticated, updateFinance); // Update finance record
router.delete("/:financeId", checkAuthenticated, deleteFinance); // Delete a finance record
// Add transactions (Expense/Revenue) to a finance record
router.post("/:financeId/transaction", checkAuthenticated, addTransaction);
export default router;
+24
View File
@@ -0,0 +1,24 @@
import express from "express";
import {
createTask,
getTasksByFarm,
getTaskById,
updateTask,
deleteTask,
updateTaskStatus,
} from "../controllers/taskController.js";
const { checkAuthenticated } = require("../Middlewares/authentication.js");
const router = express.Router();
// Routes for task management
router.post("/", checkAuthenticated, createTask); // Create a new task
router.get("/farm/:farmId", checkAuthenticated, getTasksByFarm); // Get all tasks for a specific farm
router.get("/:taskId", checkAuthenticated, getTaskById); // Get a task by ID
router.put("/:taskId", checkAuthenticated, updateTask); // Update task details
router.delete("/:taskId", checkAuthenticated, deleteTask); // Delete a task
// Update task status (Pending → Completed)
router.patch("/:taskId/status", protect, updateTaskStatus);
export default router;
+52
View File
@@ -0,0 +1,52 @@
const express = require("express");
const {
registerUser,
loginUser,
logoutUser,
updateUserDetails,
forgetPassword,
resetPassword,
getUserDetails,
updatePassword,
updatePersonalDetails,
DeleteUser,
updateUserRole,
intializeUser,
updateAvatar,
} = require("../Controllers/user.controller.js");
const { checkAuthenticated } = require("../Middlewares/authentication.js");
const upload = require("../Middlewares/multer.js");
const router = express.Router();
router.route("/register").post(registerUser);
router.route("/login").post(loginUser);
router.route("/password/forgot").post(forgetPassword);
router.route("/password/reset/:token").put(resetPassword);
router.route("/logout").get(logoutUser);
router.route("/update/:id").put(updateUserDetails);
router.route("/me").get(checkAuthenticated, getUserDetails);
router.route("/getuser").get(intializeUser);
router.route("/password/update").put(updatePassword);
router.route("/me/update").put(updatePersonalDetails);
router.route("/user/delete/:id").delete(DeleteUser);
router.route("/user/updateRole/:id").put(updateUserRole);
router
.route("/user/avatar")
.put(checkAuthenticated, upload.single("avatar"), updateAvatar);
module.exports = router;
+23
View File
@@ -0,0 +1,23 @@
const cloudinary = require("cloudinary").v2;
const fs = require("fs");
const uploadOnCloudinary = async (localFilePath) => {
try {
if (!localFilePath) return null;
const responce = await cloudinary.uploader.upload(localFilePath, {
resource_type: "auto",
});
// console.log("File is uploaded successfully");
fs.unlinkSync(localFilePath, () => {
console.log("file removed successfully");
});
return responce.url;
} catch (error) {
fs.unlinkSync(localFilePath);
console.log("file removed successfully");
return null;
}
};
module.exports = { uploadOnCloudinary };
+25
View File
@@ -0,0 +1,25 @@
const nodemailer = require("nodemailer");
const sendEmail = async (options) => {
const transporter = await nodemailer.createTransport({
service: "gmail",
host: process.env.HOST,
port: process.env.EMAIL_PORT,
secure: false,
auth: {
user: process.env.SMPT_MAIL, // senders email
pass: process.env.SMPT_PASSWORD, // app passoword created for your app by using step :: google account> manage your google account >security>enable two step verification > search app password and create password for your app
},
});
const mailOptions = {
from: "",
to: options.email,
subject: options.subject,
text: options.message,
};
await transporter.sendMail(mailOptions);
};
module.exports = sendEmail;
+41
View File
@@ -0,0 +1,41 @@
const express = require("express");
const cors = require("cors");
const cookieParser = require("cookie-parser");
const { Server } = require("socket.io");
const { createServer } = require("http");
const userRoute = require("./Routes/user.routes.js");
const farmRoute = require("./Routes/farm.routes.js");
const cropRoute = require("./Routes/crop.routes.js");
const { checkAuthenticated } = require("./Middlewares/authentication.js");
const dotenv = require("dotenv");
dotenv.config({
path: "./.env",
});
const app = express();
const corsOptions = {
origin: process.env.FRONTEND_URI,
methods: "GET,HEAD,PUT,PATCH,POST,DELETE",
credentials: true,
};
app.use(cors(corsOptions));
app.use(express.json({ limit: "16kb" }));
app.use(express.urlencoded({ extended: true, limit: "16kb" }));
app.use(express.static("public"));
app.use(cookieParser());
app.get("/", (req, res) => {
return res.send("Hiddskpkpk...");
});
app.use("/api/v1", userRoute);
app.use("/api/v1/farm", farmRoute);
app.use("/api/v1/crop", cropRoute);
module.exports = app;
+24
View File
@@ -0,0 +1,24 @@
const server = require("./app.js");
const dotenv = require("dotenv");
const cloudinary = require("cloudinary").v2;
const DB_connect = require("./Database/DB_connect.js");
const app = require("./app.js");
// dotenv Configuration
dotenv.config({
path: "./.env",
});
cloudinary.config({
cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
api_key: process.env.CLOUDINARY_API_KEY,
api_secret: process.env.CLOUDINARY_API_SECRET,
});
DB_connect();
// Listening the port
app.listen(process.env.PORT, () => {
console.log("Server is Running on ", process.env.PORT);
console.log("Frontend URI : ", process.env.FRONTEND_URI);
});
+2188
View File
File diff suppressed because it is too large Load Diff
+28
View File
@@ -0,0 +1,28 @@
{
"name": "backend",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "nodemon index.js"
},
"author": "",
"license": "ISC",
"description": "",
"dependencies": {
"bcrypt": "^5.1.1",
"cloudinary": "^2.5.1",
"cookie-parser": "^1.4.6",
"cors": "^2.8.5",
"dotenv": "^16.4.5",
"express": "^4.19.2",
"jsonwebtoken": "^9.0.2",
"mongoose": "^8.6.1",
"multer": "^1.4.5-lts.1",
"nodemailer": "^6.9.15",
"socket.io": "^4.7.5"
},
"devDependencies": {
"nodemon": "^3.1.4"
}
}