-
-
Notifications
You must be signed in to change notification settings - Fork 103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add backend for orders #405
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
MONGO_URI=enter_your_mongo_uri | ||
MONGO_URI= | ||
EMAIL_USER=your_gmail | ||
PORT=3000 | ||
EMAIL_PASS=your_16_digit_pass | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,76 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const Customer = require("../models/customer.model"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const Order = require("../models/order.model"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Create a new order | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
exports.createOrder = async (req, res) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { items } = req.body; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const customerId = req.params.id.trim(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!customerId) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return res | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.status(400) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.json({ success: false, message: "Customer ID is required." }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+7
to
+14
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Validate 'items' before calculating total amount The Apply this diff to add validation for try {
const { items } = req.body;
const customerId = req.params.id.trim();
+ if (!items || !Array.isArray(items) || items.length === 0) {
+ return res
+ .status(400)
+ .json({ success: false, message: "Order items are required and should be a non-empty array." });
+ }
+
+ // Validate each item in the array
+ for (const item of items) {
+ if (!item.price || !item.quantity) {
+ return res
+ .status(400)
+ .json({ success: false, message: "Each item must have a price and quantity." });
+ }
+ }
if (!customerId) {
return res
.status(400)
.json({ success: false, message: "Customer ID is required." });
} 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const totalAmount = items.reduce( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
(sum, item) => sum + item.price * item.quantity, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+16
to
+19
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prevent price manipulation by fetching item prices from the database Calculating Would you like assistance in modifying the code to fetch item prices from the database for secure price calculations? |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const order = new Order({ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
customer: customerId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
items, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
totalAmount, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const savedOrder = await order.save(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await Customer.findByIdAndUpdate(customerId, { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$push: { orders: savedOrder._id }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+27
to
+31
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check if customer exists before updating orders When adding a new order to a customer's record, the code assumes the customer exists. Attempting to update a non-existent customer will result in an error. It's important to verify the customer's existence before proceeding. Apply this diff to check the customer's existence: const savedOrder = await order.save();
+ const customer = await Customer.findById(customerId);
+ if (!customer) {
+ // Optionally, you might want to rollback the order creation here
+ return res
+ .status(404)
+ .json({ success: false, message: "Customer not found." });
+ }
await Customer.findByIdAndUpdate(customerId, {
$push: { orders: savedOrder._id },
});
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
res.status(201).json({ success: true, order: savedOrder }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} catch (error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
res.status(500).json({ success: false, message: error.message }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+34
to
+36
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid exposing internal error messages to clients Returning Apply this diff to return a generic error message: } catch (error) {
- res.status(500).json({ success: false, message: error.message });
+ console.error(error); // Log the detailed error message
+ res.status(500).json({ success: false, message: "An internal server error occurred." });
} Similar changes should be applied to the error handlers in the 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Get all orders for a customer | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
exports.getOrders = async (req, res) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const customerId = req.params.id.trim(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const orders = await Order.find({ customer: customerId }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+42
to
+44
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check if the customer exists before retrieving orders Currently, the code retrieves orders without verifying if the customer exists. If the customer ID is invalid or the customer does not exist, it may return an empty list or unexpected results. It's advisable to confirm the customer's existence first. Apply this diff to check the customer's existence: try {
const customerId = req.params.id.trim();
+ const customerExists = await Customer.exists({ _id: customerId });
+ if (!customerExists) {
+ return res
+ .status(404)
+ .json({ success: false, message: "Customer not found." });
+ }
const orders = await Order.find({ customer: customerId });
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
res.status(200).json({ success: true, orders }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} catch (error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
res.status(500).json({ success: false, message: error.message }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Delete an order | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
exports.deleteOrder = async (req, res) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { orderId } = req.body; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const customerId = req.params.id.trim(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+54
to
+55
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Obtain For consistency and following RESTful API conventions, it's better to pass the Apply this diff to adjust the code: try {
- const { orderId } = req.body;
+ const orderId = req.params.orderId.trim();
const customerId = req.params.id.trim(); Ensure that your route is updated to include
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const order = await Order.findOne({ _id: orderId, customer: customerId }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!order) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return res | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.status(404) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.json({ success: false, message: "Order not found" }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await Order.deleteOne({ _id: orderId }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
await Customer.findByIdAndUpdate(customerId, { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
$pull: { orders: orderId }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
res | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.status(200) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.json({ success: true, message: "Order deleted successfully" }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} catch (error) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
res.status(500).json({ success: false, message: error.message }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,4 +1,4 @@ | ||||||
/* eslint-disable no-useless-escape */ | ||||||
|
||||||
const mongoose = require("mongoose"); | ||||||
const Schema = mongoose.Schema; | ||||||
|
||||||
|
@@ -19,16 +19,30 @@ const customerSchema = new Schema( | |||||
}, | ||||||
verificationCode: { | ||||||
type: String, | ||||||
default: "" | ||||||
default: "", | ||||||
}, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider using Using an empty string as default makes it difficult to distinguish between unverified accounts and verified accounts where the code was cleared. Using - default: "",
+ default: null, 📝 Committable suggestion
Suggested change
|
||||||
role: { | ||||||
type: String, | ||||||
default: "customer", | ||||||
}, | ||||||
bio: String, | ||||||
profilePicture: String, | ||||||
|
||||||
bookedEvents: [ | ||||||
{ | ||||||
type: Schema.Types.ObjectId, | ||||||
ref: "Event", | ||||||
}, | ||||||
], | ||||||
orders: [ | ||||||
{ | ||||||
type: Schema.Types.ObjectId, | ||||||
ref: "Order", | ||||||
}, | ||||||
], | ||||||
|
||||||
Comment on lines
+31
to
+42
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider adding indexes for frequently queried fields. If you frequently query customers by their orders: [
{
type: Schema.Types.ObjectId,
ref: "Order",
+ index: true
},
],
💡 Codebase verification Add cascade delete hooks to handle orphaned references The referenced models (
Example implementation for Event model: eventSchema.pre('remove', async function(next) {
await mongoose.model('Customer').updateMany(
{ bookedEvents: this._id },
{ $pull: { bookedEvents: this._id } }
);
next();
}); 🔗 Analysis chainVerify referenced models and consider orphaned data handling. Ensure that:
Let me check the cascade delete behavior in these models to complete the verification. 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Check if referenced models exist
echo "Checking for Event model..."
rg -l "mongoose\.model\(.*Event.*\)" backend/models/
echo "Checking for Order model..."
rg -l "mongoose\.model\(.*Order.*\)" backend/models/
Length of output: 300 Script: #!/bin/bash
# Check Event model implementation for cascade delete
echo "Event model implementation:"
cat backend/models/events.model.js
echo -e "\nOrder model implementation:"
cat backend/models/order.model.js
# Check if there are any pre/post delete hooks in the models
echo -e "\nChecking for delete hooks:"
rg "pre\('delete'" backend/models/
rg "post\('delete'" backend/models/
Length of output: 2116 |
||||||
}, | ||||||
{ timestamps: true }, | ||||||
{ timestamps: true } | ||||||
); | ||||||
|
||||||
const Customer = mongoose.model("Customer", customerSchema); | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update contributor information consistently.
The changes to contributor information are mostly correct, but there are some inconsistencies:
Please make the following adjustments:
Also applies to: 330-333, 337-340, 351-356, 358-361, 380-386