21CSS301T FULL STACK DEVELOPMENT
Tutorials-3
ExNo:7 [Link] based Web development 13 -04-2025
Give a simple [Link]-based web development example that demonstrates how to
handle various built-in APIs (modules) in [Link] — like HTTP, File System (fs),
Path, and URL — without [Link], to show how Node alone can manage web
requests.
const fs = require("fs");
const path = require("path");
const csv = require("csv-parser");
let cachedFoods = null;
const MEAL_ORDER = ["Breakfast", "Lunch", "Evening Snack", "Dinner"];
const MEAL_RANGES = {
Breakfast: { min: 250, max: 350 },
Lunch: { min: 400, max: 550 },
"Evening Snack": { min: 150, max: 250 },
Dinner: { min: 300, max: 450 },
};
const DESSERT_OR_JUNK_KEYWORDS = [
"halwa",
"kheer",
"cake",
"pastry",
"ice cream",
"kulfi",
"laddu",
"jalebi",
"gulab jamun",
"sweet",
"dessert",
"chocolate",
"cola",
"soda",
"punch",
"milkshake",
"shake",
"falooda",
"fried",
"pakoda",
"samosa",
"chips",
];
const BREAKFAST_KEYWORDS = [
"oats",
"poha",
"idli",
"upma",
"dosa",
"uttapam",
"paratha",
"sandwich",
"sprout",
"milk",
"boiled egg",
"omelette",
"fruit",
"banana",
];
const LUNCH_DINNER_KEYWORDS = [
"dal",
"chapati",
"roti",
"phulka",
"rice",
"khichdi",
"rajma",
"chole",
"paneer",
"sabzi",
"vegetable",
"sambar",
"curry",
"tofu",
"fish",
"chicken",
"egg curry",
];
const SNACK_KEYWORDS = [
"fruit",
"salad",
"sprout",
"soup",
"chana",
"makhana",
"nuts",
"corn",
"buttermilk",
"lassi",
"tea",
"coffee",
"coconut water",
];
const HEALTHY_PRIORITY_KEYWORDS = [
"oats",
"poha",
"idli",
"dal",
"chapati",
"roti",
"vegetable",
"sabzi",
"salad",
"fruit",
"paneer",
"sprout",
"khichdi",
"rajma",
"chole",
"sambar",
"upma",
"dosa",
];
const NON_VEG_KEYWORDS = [
"chicken",
"mutton",
"fish",
"prawn",
"meat",
"keema",
];
const EGG_KEYWORDS = ["egg", "omelette", "omelet", "boiled egg"];
const toNumber = (value) => {
const parsed = Number(value);
return [Link](parsed) ? parsed : 0;
};
const includesAnyKeyword = (text, keywords) => {
const name = String(text || "").toLowerCase();
return [Link]((keyword) => [Link](keyword));
};
const inferFoodFlags = (dishName) => {
const lowerName = String(dishName || "").toLowerCase();
const isNonVeg = includesAnyKeyword(lowerName, NON_VEG_KEYWORDS);
const hasEgg = includesAnyKeyword(lowerName, EGG_KEYWORDS);
return {
isNonVeg,
hasEgg,
isVeg: !isNonVeg && !hasEgg,
};
};
const normalizeDietPreference = (dietPreference) => {
const value = String(dietPreference || "veg").toLowerCase().trim();
if (["non-veg", "non veg", "nonveg", "non_veg", "nonvegetarian", "non-
vegetarian"].includes(value)) {
return "non-veg";
}
if (["egg", "eggetarian", "eggeterian", "eggitarian"].includes(value)) {
return "eggetarian";
}
if (value === "vegan") {
return "vegan";
}
return "veg";
};
const isNonVegPreferredItem = (food) => {
return Boolean(food?.flags?.isNonVeg || food?.flags?.hasEgg);
};
const isEggPreferredItem = (food) => {
return Boolean(food?.flags?.hasEgg && !food?.flags?.isNonVeg);
};
const isAllowedByDietPreference = (food, dietPreference) => {
const normalizedPreference = normalizeDietPreference(dietPreference);
if (normalizedPreference === "non-veg") {
return true;
}
if (normalizedPreference === "eggetarian") {
return ![Link];
}
// veg and vegan use same filter due to dataset limitations.
return [Link];
};
const getMealKeywords = (mealType) => {
if (mealType === "Breakfast") {
return BREAKFAST_KEYWORDS;
}
if (mealType === "Evening Snack") {
return SNACK_KEYWORDS;
}
return LUNCH_DINNER_KEYWORDS;
};
const mealTypeScore = (dishName, mealType) => {
const keywords = getMealKeywords(mealType);
return includesAnyKeyword(dishName, keywords) ? 1 : 0;
};
const avoidForWeightLoss = (food) => {
if ([Link] > 10) {
return true;
}
if ([Link] > 20) {
return true;
}
return includesAnyKeyword([Link],
DESSERT_OR_JUNK_KEYWORDS);
};
const healthyScore = (dishName) => {
return includesAnyKeyword(dishName, HEALTHY_PRIORITY_KEYWORDS) ? 1
: 0;
};
const inRange = (value, min, max) => value >= min && value <= max;
const getCsvPath = () => {
const configured = [Link].INDIAN_FOOD_CSV_PATH;
const candidates = [
configured,
"../../indian_food.csv",
"../indian_food.csv",
].filter(Boolean);
for (const candidate of candidates) {
const resolved = [Link](__dirname, candidate);
if ([Link](resolved)) {
return resolved;
}
}
return [Link](__dirname, "../../indian_food.csv");
};
const loadIndianFoodData = async () => {
if (cachedFoods) {
return cachedFoods;
}
const csvPath = getCsvPath();
return new Promise((resolve, reject) => {
const foods = [];
[Link](csvPath)
.pipe(csv())
.on("data", (row) => {
const dishName = row["Dish Name"] || "Unknown Dish";
[Link]({
dishName,
calories: toNumber(row["Calories (kcal)"]),
carbs: toNumber(row["Carbohydrates (g)"]),
protein: toNumber(row["Protein (g)"]),
fats: toNumber(row["Fats (g)"]),
freeSugar: toNumber(row["Free Sugar (g)"]),
flags: inferFoodFlags(dishName),
});
})
.on("end", () => {
cachedFoods = [Link]((food) => [Link] > 0);
resolve(cachedFoods);
})
.on("error", (error) => {
reject(error);
});
});
};
const sortByQuality = (pool, mealType, targetCalories) => {
return [...pool].sort((a, b) => {
const aMealScore = mealTypeScore([Link], mealType);
const bMealScore = mealTypeScore([Link], mealType);
if (aMealScore !== bMealScore) {
return bMealScore - aMealScore;
}
const aHealthy = healthyScore([Link]);
const bHealthy = healthyScore([Link]);
if (aHealthy !== bHealthy) {
return bHealthy - aHealthy;
}
const aDiff = [Link]([Link] - targetCalories);
const bDiff = [Link]([Link] - targetCalories);
return aDiff - bDiff;
});
};
const selectMealCandidate = ({
foods,
mealType,
dietPreference,
healthGoal,
range,
usedNames,
targetCalories,
}) => {
const byPreference = [Link]((food) => isAllowedByDietPreference(food,
dietPreference));
const byGoal =
healthGoal === "weight-loss"
? [Link]((food) => !avoidForWeightLoss(food))
: byPreference;
const primaryPool = [Link](
(food) => inRange([Link], [Link], [Link]) && !
[Link]([Link])
);
const secondaryPool = [Link]((food) => );
const fallbackPool = [Link]((food) => !
[Link]([Link]));
const isMealMatched = (food) => mealTypeScore([Link], mealType) > 0;
const strictMealPool = [Link](isMealMatched);
const looseMealPool = [Link](isMealMatched);
const healthyPrimaryPool = [Link]((food) =>
healthyScore([Link]) > 0);
const healthySecondaryPool = [Link]((food) =>
healthyScore([Link]) > 0);
const preferenceHealthyFallbackPool = [Link](
(food) => isMealMatched(food) || healthyScore([Link]) > 0
);
const pool =
[Link] > 0
? strictMealPool
: [Link] > 0
? healthyPrimaryPool
: [Link] > 0
? primaryPool
: [Link] > 0
? looseMealPool
: [Link] > 0
? healthySecondaryPool
: [Link] > 0
? secondaryPool
: [Link] > 0
? preferenceHealthyFallbackPool
: fallbackPool;
if (![Link]) {
return null;
}
// For non-veg users, prefer non-veg/egg options when available in the selected pool.
const normalizedPreference = normalizeDietPreference(dietPreference);
let prioritizedPool = pool;
if (normalizedPreference === "non-veg") {
const nonVegFirst = [Link](isNonVegPreferredItem);
prioritizedPool = [Link] > 0 ? nonVegFirst : pool;
}
if (normalizedPreference === "eggetarian") {
const eggFirst = [Link](isEggPreferredItem);
prioritizedPool = [Link] > 0 ? eggFirst : pool;
}
const sorted = sortByQuality(prioritizedPool, mealType, targetCalories);
return sorted[0] || null;
};
const clamp = (value, min, max) => {
if (value < min) return min;
if (value > max) return max;
return value;
};
const getServingMultiplier = (calories, range) => {
if (!calories || calories <= 0) {
return 1;
}
if (calories < [Link]) {
return clamp([Link] / calories, 1, 2);
}
if (calories > [Link]) {
return clamp([Link] / calories, 0.6, 1);
}
return 1;
};
const calculateMealTarget = (dailyCalories, mealType) => {
const ratioMap = {
Breakfast: 0.25,
Lunch: 0.35,
"Evening Snack": 0.15,
Dinner: 0.25,
};
const ratioTarget = [Link](dailyCalories * ratioMap[mealType]);
const range = MEAL_RANGES[mealType];
return clamp(ratioTarget, [Link], [Link]);
};
const toMealResponse = (mealType, food, range) => {
if (!food) {
return {
mealType,
dishName: "No suitable item found",
calories: 0,
protein: 0,
carbs: 0,
fats: 0,
};
}
const servingMultiplier = getServingMultiplier([Link], range);
const adjustedCalories = clamp([Link]([Link] * servingMultiplier),
[Link], [Link]);
return {
mealType,
dishName:
servingMultiplier === 1
? [Link]
: `${[Link]} (${[Link](1)}x serving)`,
calories: adjustedCalories,
protein: Number(([Link] * servingMultiplier).toFixed(2)),
carbs: Number(([Link] * servingMultiplier).toFixed(2)),
fats: Number(([Link] * servingMultiplier).toFixed(2)),
};
};
const generateDietPlanMeals = async ({
dailyCalories,
dietPreference,
healthGoal,
usedDishNames = new Set(),
}) => {
const foodData = await loadIndianFoodData();
if (![Link]) {
return [];
}
const usedNames = new Set(usedDishNames);
return MEAL_ORDER.map((mealType) => {
const range = MEAL_RANGES[mealType];
const targetCalories = calculateMealTarget(dailyCalories, mealType);
const picked = selectMealCandidate({
foods: foodData,
mealType,
dietPreference,
healthGoal,
range,
usedNames,
targetCalories,
});
if (picked) {
[Link]([Link]);
}
return toMealResponse(mealType, picked, range);
});
};
[Link] = {
loadIndianFoodData,
generateDietPlanMeals,
};
ExNo:8 [Link]-based web development 13-04-2025
Write a simple [Link]-based web development example that demonstrates how
to handle various APIs using Express along with [Link] modules like fs, path, and
HTTP methods (GET, POST, etc.).
const express = require("express");
const cors = require("cors");
const dotenv = require("dotenv");
const connectDB = require("./config/db");
const trackApiUsage = require("./middleware/trackApiUsage");
[Link]();
connectDB();
const app = express();
const PORT = [Link] || 5000;
const parseAllowedOrigins = () => {
const raw = [Link].FRONTEND_URL || "[Link]
return raw
.split(",")
.map((value) => [Link]())
.filter(Boolean);
};
[Link](
cors({
origin: (origin, callback) => {
const allowedOrigins = parseAllowedOrigins();
// Allow tools like Postman (no origin) and local Vite dev ports.
if (!origin || [Link](origin) || /^http:\/\/localhost:5\
d{3}$/.test(origin)) {
callback(null, true);
return;
}
callback(new Error("CORS blocked for this origin"));
},
credentials: true,
})
);
[Link]([Link]());
[Link](trackApiUsage);
[Link]("/", (req, res) => {
[Link]({
message: "AI Diet Planner backend is running",
health: "/api/health",
});
});
[Link]("/api/health", (req, res) => {
[Link]({ message: "AI Diet Planner API is running" });
});
[Link]("/api/auth", require("./routes/authRoutes"));
[Link]("/api/profile", require("./routes/profileRoutes"));
[Link]("/api/diet-plans", require("./routes/dietRoutes"));
[Link]("/api/foods", require("./routes/foodRoutes"));
[Link]("/api/recipes", require("./routes/recipeRoutes"));
[Link]("/api/meal-logs", require("./routes/mealLogRoutes"));
[Link]("/api/progress", require("./routes/progressRoutes"));
[Link]("/api/seed", require("./routes/seedRoutes"));
[Link]("/api/generate-diet", require("./routes/generateDietRoutes"));
[Link]("/api/chatbot", require("./routes/chatbotRoutes"));
[Link]("/api/admin", require("./routes/adminRoutes"));
[Link]((err, req, res, next) => {
[Link](err);
[Link](500).json({ message: "Something went wrong" });
});
[Link](PORT, () => {
[Link](`Server running on [Link]
});