Skip to content

Commit 7bf0761

Browse files
committed
Add: Task1 Solution
0 parents  commit 7bf0761

File tree

16 files changed

+5042
-0
lines changed

16 files changed

+5042
-0
lines changed

.gitignore

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
artifacts
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
lerna-debug.log*
8+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
9+
pids
10+
*.pid
11+
*.seed
12+
*.pid.lock
13+
lib-cov
14+
coverage
15+
*.lcov
16+
.nyc_output
17+
.grunt
18+
bower_components
19+
.lock-wscript
20+
build/Release
21+
node_modules/
22+
jspm_packages/
23+
typings/
24+
*.tsbuildinfo
25+
.npm
26+
.eslintcache
27+
.rpt2_cache/
28+
.rts2_cache_cjs/
29+
.rts2_cache_es/
30+
.rts2_cache_umd/
31+
.node_repl_history
32+
*.tgz
33+
.yarn-integrity
34+
.env
35+
.env.test
36+
.cache
37+
.next
38+
.nuxt
39+
dist
40+
.cache/
41+
.vuepress/dist
42+
.serverless/
43+
.fusebox/
44+
.dynamodb/
45+
.tern-port
46+
*/node_modules
47+
.idea
48+
unit.xml
49+
junit.xml

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Food Delivery App
2+
3+
4+
5+
**Commands**
6+
7+
- run:
8+
9+
```bash
10+
npm start
11+
```
12+
13+
- install:
14+
15+
```bash
16+
npm install
17+
```

config.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"reporterEnabled": "spec, mocha-junit-reporter",
3+
"mochaJunitReporterReporterOptions": {
4+
"mochaFile": "unit.xml"
5+
}
6+
}

controllers/menuController.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
const fs = require("fs");
2+
const path = require("path");
3+
const dataPath = path.join(__dirname, "../data/restaurants.json");
4+
const writePath = path.join(__dirname, "../data/updated_restaurants.json");
5+
6+
const readRestaurants = () => {
7+
return JSON.parse(fs.readFileSync(dataPath, "utf8"));
8+
};
9+
10+
const writeRestaurants = (restaurants) => {
11+
fs.writeFileSync(writePath, JSON.stringify(restaurants, null, 2));
12+
};
13+
14+
15+
const addItem = async (restaurantId, menuItem) => {
16+
let restaurants = await readRestaurants();
17+
const restaurantIndex = restaurants.findIndex((r) => r.id === restaurantId);
18+
19+
if (restaurantIndex === -1) {
20+
const error = new Error(`Restaurant with ID ${restaurantId} not found.`);
21+
error.status = 404;
22+
throw error;
23+
}
24+
25+
restaurants[restaurantIndex].menu.push(menuItem);
26+
await writeRestaurants(restaurants);
27+
28+
return restaurants[restaurantIndex].menu;
29+
};
30+
31+
exports.addMenuItem = async (req, res) => {
32+
const { restaurantId } = req.params;
33+
const newItem = req.body;
34+
35+
const result = await addItem(restaurantId, newItem);
36+
if (result.error) {
37+
return res.status(400).json({ error: result.error });
38+
}
39+
res
40+
.status(201)
41+
.json({ message: "Menu item added successfully", menu: result });
42+
};
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
const fs = require("fs");
2+
const path = require("path");
3+
4+
const restaurants = JSON.parse(
5+
fs.readFileSync(path.join(__dirname, "../data/restaurants.json"), "utf8")
6+
);
7+
8+
exports.getData = (req, res) => {
9+
const { cuisine, location, rating, availability } = req.query;
10+
11+
let filteredRestaurants = restaurants;
12+
13+
if (cuisine) {
14+
filteredRestaurants = filteredRestaurants.filter((restaurant) =>
15+
restaurant.cuisine.some((c) => c.toLowerCase() === cuisine.toLowerCase())
16+
);
17+
}
18+
if (location) {
19+
filteredRestaurants = filteredRestaurants.filter(
20+
(restaurant) =>
21+
restaurant.location.toLowerCase() === location.toLowerCase()
22+
);
23+
}
24+
if (rating) {
25+
const minRating = parseFloat(rating);
26+
filteredRestaurants = filteredRestaurants.filter(
27+
(restaurant) => restaurant.rating >= minRating
28+
);
29+
}
30+
if (availability !== undefined) {
31+
const isAvailable = availability === "true";
32+
filteredRestaurants = filteredRestaurants.filter(
33+
(restaurant) => restaurant.availability === isAvailable
34+
);
35+
}
36+
37+
res.status(200).json(filteredRestaurants);
38+
};

data/restaurants.json

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
[
2+
{
3+
"id": "1",
4+
"name": "Tasty Bites",
5+
"location": "Downtown",
6+
"cuisine": ["Indian", "Chinese"],
7+
"rating": 4.5,
8+
"availability": true,
9+
"menu": [
10+
{
11+
"itemId": "201",
12+
"name": "Butter Chicken",
13+
"price": 12.99,
14+
"category": "Main Course",
15+
"availability": true
16+
},
17+
{
18+
"itemId": "202",
19+
"name": "Fried Rice",
20+
"price": 8.99,
21+
"category": "Main Course",
22+
"availability": true
23+
}
24+
]
25+
},
26+
{
27+
"id": "2",
28+
"name": "Pasta Palace",
29+
"location": "Uptown",
30+
"cuisine": ["Italian"],
31+
"rating": 4.2,
32+
"availability": false,
33+
"menu": [
34+
{
35+
"itemId": "203",
36+
"name": "Spaghetti Carbonara",
37+
"price": 10.99,
38+
"category": "Main Course",
39+
"availability": true
40+
}
41+
]
42+
},
43+
{
44+
"id": "3",
45+
"name": "Sushi Haven",
46+
"location": "Midtown",
47+
"cuisine": ["Japanese"],
48+
"rating": 4.8,
49+
"availability": true,
50+
"menu": [
51+
{
52+
"itemId": "204",
53+
"name": "Salmon Sushi",
54+
"price": 15.99,
55+
"category": "Sushi",
56+
"availability": true
57+
},
58+
{
59+
"itemId": "205",
60+
"name": "Miso Soup",
61+
"price": 4.99,
62+
"category": "Soup",
63+
"availability": true
64+
}
65+
]
66+
},
67+
{
68+
"id": "4",
69+
"name": "Burger Barn",
70+
"location": "Downtown",
71+
"cuisine": ["American"],
72+
"rating": 4.3,
73+
"availability": true,
74+
"menu": [
75+
{
76+
"itemId": "206",
77+
"name": "Cheeseburger",
78+
"price": 9.99,
79+
"category": "Main Course",
80+
"availability": true
81+
},
82+
{
83+
"itemId": "207",
84+
"name": "French Fries",
85+
"price": 3.99,
86+
"category": "Side",
87+
"availability": true
88+
}
89+
]
90+
},
91+
{
92+
"id": "5",
93+
"name": "Taco Fiesta",
94+
"location": "Suburbs",
95+
"cuisine": ["Mexican"],
96+
"rating": 4.6,
97+
"availability": false,
98+
"menu": [
99+
{
100+
"itemId": "208",
101+
"name": "Chicken Tacos",
102+
"price": 7.99,
103+
"category": "Main Course",
104+
"availability": false
105+
},
106+
{
107+
"itemId": "209",
108+
"name": "Guacamole",
109+
"price": 5.49,
110+
"category": "Appetizer",
111+
"availability": true
112+
}
113+
]
114+
},
115+
{
116+
"id": "6",
117+
"name": "Vegan Delight",
118+
"location": "Midtown",
119+
"cuisine": ["Vegan"],
120+
"rating": 4.7,
121+
"availability": true,
122+
"menu": [
123+
{
124+
"itemId": "210",
125+
"name": "Vegan Burger",
126+
"price": 10.49,
127+
"category": "Main Course",
128+
"availability": true
129+
},
130+
{
131+
"itemId": "211",
132+
"name": "Quinoa Salad",
133+
"price": 8.99,
134+
"category": "Salad",
135+
"availability": true
136+
}
137+
]
138+
}
139+
]

hackerrank.yml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
version: 1.0
2+
configuration:
3+
has_webserver: true
4+
readonly_paths:
5+
- test/task1/index.spec.js
6+
- test/task1/mocha.opts
7+
- test/task2/index.spec.js
8+
- test/task2/mocha.opts
9+
- test/task3/index.spec.js
10+
- test/task3/mocha.opts
11+
- test/task4/index.spec.js
12+
- test/task4/mocha.opts
13+
- test/task5/index.spec.js
14+
- test/task5/mocha.opts
15+
- data/restaurantOwners.json
16+
- data/restaurants.json
17+
- data/orders.json
18+
scoring:
19+
command: echo "No test command configured for this branch. Use task level testcases."
20+
files:
21+
- unit.xml
22+
ide_config:
23+
default_open_files:
24+
- index.js
25+
project_menu:
26+
run: npm start
27+
install: npm install
28+
test: echo "No test command configured for this branch. Use task level testcases."

index.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
const express = require("express");
3+
const { json } = require("express");
4+
const app = express();
5+
const PORT = process.env.PORT || 8000;
6+
7+
const restaurantRoutes = require("./routes/restaurantRoutes.js");
8+
const menuRoutes = require("./routes/menuRoutes.js");
9+
10+
app.use(json());
11+
12+
app.get('/', (req, res) => {
13+
res.send('<h1>Welcome to Food Delivery Platform</h1>');
14+
});
15+
16+
// Routes
17+
app.use("/restaurants", restaurantRoutes);
18+
app.use("/menu", menuRoutes);
19+
20+
app.listen(PORT, () => {
21+
console.log(`Server is running on http://localhost:${PORT}`);
22+
});
23+
24+
module.exports = app;

middleware/validateMenu.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
exports.validateMenu = (req, res, next) => {
2+
const { itemId, name, price, category, availability } = req.body;
3+
let errors = [];
4+
5+
if (!itemId)
6+
errors.push({ field: "itemId", message: "Item ID is required." });
7+
if (!name) errors.push({ field: "name", message: "Field name is required." });
8+
if (!category)
9+
errors.push({ field: "category", message: "Category is required." });
10+
if (price === undefined)
11+
errors.push({ field: "price", message: "Price is required." });
12+
if (availability === undefined)
13+
errors.push({
14+
field: "availability",
15+
message: "Availability is required.",
16+
});
17+
18+
if (price !== undefined && (typeof price !== "number" || price <= 0)) {
19+
errors.push({
20+
field: "price",
21+
message: "Price must be a valid number greater than 0.",
22+
});
23+
}
24+
25+
if (availability !== undefined && typeof availability !== "boolean") {
26+
errors.push({
27+
field: "availability",
28+
message: "Availability should be boolean.",
29+
});
30+
}
31+
32+
if (errors.length > 0) {
33+
return res.status(400).json({ errors });
34+
}
35+
next();
36+
};

output/.gitkeep

Whitespace-only changes.

0 commit comments

Comments
 (0)