Develop an Express application with TypeScript, integrating MongoDB with Mongoose to manage a Bike Store. Ensure data integrity using Mongoose schema validation.
- Create an Express project with TypeScript.
- Set up a MongoDB database to store Products (bikes) and Orders.
- Use Mongoose for schema definition and data operations.
- Implement CRUD operations for both bikes and orders.
- Product Model (Bike)
- name (string): The name of the bike.
- brand (string): The manufacturer or brand of the bike.
- price (number): Price of the bike.
- category (string): Type of bike (e.g., Mountain, Road, Hybrid, Electric). Use
enum
with exact values (Mountain
,Road
,Hybrid
,Electric
). - description (string): A brief description of the bike.
- quantity (number): Quantity of the bike available.
- inStock (boolean): Indicates if the bike is in stock.
- Order Model
- email (string): The email address of the customer.
- product (ObjectId): The bike ordered (
unused ref
). (Enter the created productId from your database that represents the bike you want to purchase.) - quantity (number): The quantity of the ordered bike.
- totalPrice (number): The total price (product price * quantity).
message
: A brief error message explaining what went wrong.success
: Set tofalse
for error responses.error
: The error message or error object returned by the application (e.g.,"ValidationError"
,"Resource not found"
).stack
: The stack trace showing where the error occurred in the code.
{
"message": "Validation failed",
"success": false,
"error": {
"name": "ValidationError",
"errors": {
"price": {
"message": "Price must be a positive number",
"name": "ValidatorError",
"properties": {
"message": "Price must be a positive number",
"type": "min",
"min": 0
},
"kind": "min",
"path": "price",
"value": -5
}
}
},
"stack": "Error: Something went wrong\n at app.js:23:13\n at..."
}
- Endpoint:
/api/products
- Method:
POST
- Request Body:
{
"name": "Xtreme Mountain Bike",
"brand": "Giant",
"price": 1200,
"category": "Mountain",
"description": "A high-performance bike built for tough terrains.",
"quantity": 50,
"inStock": true
}
- Response: Success message and created bike details.
{
"message": "Bike created successfully",
"success": true,
"data": {
"_id": "648a45e5f0123c45678d9012",
"name": "Xtreme Mountain Bike",
"brand": "Giant",
"price": 1200,
"category": "Mountain",
"description": "A high-performance bike built for tough terrains.",
"quantity": 50,
"inStock": true,
"createdAt": "2024-11-19T10:23:45.123Z",
"updatedAt": "2024-11-19T10:23:45.123Z"
}
}
- Endpoint:
/api/products
- Method:
GET
- Response: A list of all bikes with details like name, brand, price, category, etc.
- Query: A list of all bikes from the same category, accessed via
/api/products?searchTerm=category
.searchTerm
can bename
,brand
, orcategory
.
{
"message": "Bikes retrieved successfully",
"status": true,
"data": [
{
"_id": "648a45e5f0123c45678d9012",
"name": "Xtreme Mountain Bike",
"brand": "Giant",
"price": 1200,
"category": "Mountain",
"description": "A high-performance bike built for tough terrains.",
"quantity": 50,
"inStock": true,
"createdAt": "2024-11-19T10:23:45.123Z",
"updatedAt": "2024-11-19T10:23:45.123Z"
}
// ... rest data
]
}
- Endpoint:
/api/products/:productId
- Method:
GET
- Response: The details of a specific bike by ID.
{
"message": "Bike retrieved successfully",
"status": true,
"data": {
"_id": "648a45e5f0123c45678d9012",
"name": "Xtreme Mountain Bike",
"brand": "Giant",
"price": 1200,
"category": "Mountain",
"description": "A high-performance bike built for tough terrains.",
"quantity": 50,
"inStock": true,
"createdAt": "2024-11-19T10:23:45.123Z",
"updatedAt": "2024-11-19T10:23:45.123Z"
}
}
- Endpoint:
/api/products/:productId
- Method:
PUT
- Request Body: (Bike details to update)
{
"price": 1300,
"quantity": 30
}
- Response: Success message and updated bike details.
{
"message": "Bike updated successfully",
"status": true,
"data": {
"_id": "648a45e5f0123c45678d9012",
"name": "Xtreme Mountain Bike",
"brand": "Giant",
"price": 1300, // Price updated
"category": "Mountain",
"description": "A high-performance bike built for tough terrains.",
"quantity": 30, // Quantity updated
"inStock": true,
"createdAt": "2024-11-19T10:23:45.123Z",
"updatedAt": "2024-11-19T11:00:00.000Z" // Updated timestamp
}
}
- Endpoint:
/api/products/:productId
- Method:
DELETE
- Response: Success message confirming the bike has been deleted.
{
"message": "Bike deleted successfully",
"status": true,
"data": {}
}
- Endpoint:
/api/orders
- Method:
POST
- Inventory Management Logic:
- When an order is placed, reduce the quantity in the product model.
- If the inventory quantity goes to zero, set inStock to
false
. - Handle insufficient stock cases by returning an appropriate error message.
- Request Body:
{
"email": "[email protected]",
"product": "648a45e5f0123c45678d9012",
"quantity": 2,
"totalPrice": 2400
}
- Response: Success message confirming the order.
{
"message": "Order created successfully",
"status": true,
"data": {
"_id": "648b45f5e1234b56789a6789",
"email": "[email protected]",
"product": "648a45e5f0123c45678d9012",
"quantity": 2,
"totalPrice": 2400,
"createdAt": "2024-11-19T12:00:00.000Z",
"updatedAt": "2024-11-19T12:00:00.000Z"
}
}
- Endpoint:
/api/orders/revenue
- Method:
GET
- Aggregation Suggestion:
- Use MongoDB aggregation pipeline to calculate the total revenue from
all orders
. - Calculate the total price by multiplying the price of each bike by the quantity ordered.
- Use MongoDB aggregation pipeline to calculate the total revenue from
- Response: The total revenue from all orders.
{
"message": "Revenue calculated successfully",
"status": true,
"data": {
"totalRevenue": 3600 // Total revenue calculated from all orders
}
}
- Code Quality:
- Write clean, well-documented code.
- Use meaningful variable and function names.
- API Structure:
- API endpoints should be the same as we have provided. If you don't follow the API structure and response structure your mark will be deducted.
- Follow the API structure exactly as outlined above.
- Ensure request and response formats match the specifications.
- Error Handling:
- Implement proper error handling for scenarios like invalid input, missing data, and insufficient stock.
- Not Found: If a book or order is not found, return a
404
error with an appropriate message. - Validation Errors: Return specific error messages for validation failures (e.g., invalid email, insufficient stock).
- Video Explanation:
- Record a video explaining the key features of your Book Store API and the logic behind its design and test APIs.
- GitHub Repository Link
- Live Deployment Link
- Video Explanation (Public Link)
- Professional README file with features of your application and instructions on setting up the project locally.
- 60 Marks: November 24, 2024 - 11:59 PM
- 50 Marks: November 25, 2024 - 11:59 PM
- 30 Marks: After November 25, 2024