Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions controller/accountController.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
const getMealPlanByUserIdAndDate = require('../model/getMealPlanByUserIdAndDate.js');

function resolveAccountUserId(req) {
const requestUserId = req.query?.user_id;
const currentUserId = req.user?.userId;
const role = String(req.user?.role || '').toLowerCase();

if ((role === 'admin' || role === 'nutritionist') && requestUserId) {
return requestUserId;
}

return currentUserId;
}

const getAllAccount = async (req, res) => {
try {
const { user_id, created_at } = req.query;
const { created_at } = req.query;
const user_id = resolveAccountUserId(req);

const mealPlans = await getMealPlanByUserIdAndDate(user_id, created_at);

Expand All @@ -19,4 +32,4 @@ const getAllAccount = async (req, res) => {

module.exports = {
getAllAccount
};
};
39 changes: 31 additions & 8 deletions controller/appointmentController.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,22 @@ function validationFailure(res, errors) {
return res.status(400).json({ errors: errors.array() });
}

function resolveAppointmentUserId(req) {
const requestUserId =
req.body?.userId ||
req.body?.user_id ||
req.query?.userId ||
req.query?.user_id;
const currentUserId = req.user?.userId;
const role = String(req.user?.role || '').toLowerCase();

if (role === 'admin' || role === 'nutritionist') {
return requestUserId || currentUserId;
}

return currentUserId;
}

function internalFailure(res, label, error, context = {}) {
logger.error(label, { error: error.message, ...context });
return res.status(500).json({ error: 'Internal server error' });
Expand All @@ -23,7 +39,8 @@ const saveAppointment = async (req, res) => {
if (!errors.isEmpty()) {
return validationFailure(res, errors);
}
const { userId, date, time, description } = req.body;
const userId = resolveAppointmentUserId(req);
const { date, time, description } = req.body;
try {
await addAppointment(userId, date, time, description);
res.status(201).json({ message: 'Appointment saved successfully' });
Expand All @@ -37,7 +54,8 @@ const saveAppointmentV2 = async (req, res) => {
if (!errors.isEmpty()) {
return validationFailure(res, errors);
}
const { userId, title, doctor, type, date, time, location, address, phone, notes, reminder } = req.body;
const userId = resolveAppointmentUserId(req);
const { title, doctor, type, date, time, location, address, phone, notes, reminder } = req.body;
try {
const appointment = await addAppointmentModelV2({
userId, title, doctor, type, date, time, location, address, phone, notes, reminder,
Expand All @@ -54,32 +72,37 @@ const updateAppointment = async (req, res) => {
return validationFailure(res, errors);
}
const { id } = req.params;
const userId = resolveAppointmentUserId(req);
const { title, doctor, type, date, time, location, address, phone, notes, reminder } = req.body;
try {
const updatedAppointment = await updateAppointmentModel(id, {
const updatedAppointment = await updateAppointmentModel(id, userId, {
title, doctor, type, date, time, location, address, phone, notes, reminder,
});
if (!updatedAppointment) {
return res.status(404).json({ message: 'Appointment not found' });
}
res.status(200).json({ message: 'Appointment updated successfully', appointment: updatedAppointment });
} catch (error) {
return internalFailure(res, 'Error updating appointment', error, { appointmentId: id });
return internalFailure(res, 'Error updating appointment', error, { appointmentId: id, userId });
}
};

const delAppointment = async (req, res) => {
const { id } = req.params;
const userId = resolveAppointmentUserId(req);
try {
const deleted = await deleteAppointmentById(id);
const deleted = await deleteAppointmentById(id, userId);
if (!deleted) {
return res.status(404).json({ message: 'Appointment not found' });
}
res.status(200).json({ message: 'Appointment deleted successfully' });
} catch (error) {
return internalFailure(res, 'Error deleting appointment', error, { appointmentId: id });
return internalFailure(res, 'Error deleting appointment', error, { appointmentId: id, userId });
}
};

const getAppointments = async (req, res) => {
const userId = req.query.userId || req.user?.id || req.user?.user_id;
const userId = resolveAppointmentUserId(req);
try {
const appointments = await getAppointmentsByUserId(userId);
res.status(200).json(appointments);
Expand All @@ -93,7 +116,7 @@ const getAppointmentsV2 = async (req, res) => {
const page = parseInt(req.query.page, 10) || 1;
const pageSize = parseInt(req.query.pageSize, 10) || 10;
const search = req.query.search || '';
const userId = req.query.userId || req.user?.id || req.user?.user_id;
const userId = resolveAppointmentUserId(req);
const from = (page - 1) * pageSize;
const to = from + pageSize - 1;

Expand Down
27 changes: 21 additions & 6 deletions controller/chatbotController.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,23 @@ function handleUnexpectedError(res, label, error, context = {}) {
);
}

function resolveChatbotUserId(req) {
const requestUserId = req.body?.user_id || req.query?.user_id;
const currentUserId = req.user?.userId;
const role = String(req.user?.role || '').toLowerCase();

if ((role === 'admin' || role === 'nutritionist') && requestUserId) {
return requestUserId;
}

return currentUserId;
}

async function getChatResponse(req, res) {
try {
const userId = resolveChatbotUserId(req);
const result = await chatbotService.getChatResponse({
userId: req.body.user_id,
userId,
userInput: req.body.user_input
});
return res.status(result.statusCode).json(result.body);
Expand All @@ -38,7 +51,7 @@ async function getChatResponse(req, res) {
}

return handleUnexpectedError(res, 'Error in chatbot response', error, {
userId: req.body.user_id
userId: resolveChatbotUserId(req)
});
}
}
Expand Down Expand Up @@ -73,30 +86,32 @@ async function addPDF(req, res) {

async function getChatHistory(req, res) {
try {
const result = await chatbotService.getChatHistory(req.body.user_id);
const userId = resolveChatbotUserId(req);
const result = await chatbotService.getChatHistory(userId);
return res.status(result.statusCode).json(result.body);
} catch (error) {
if (isServiceError(error)) {
return res.status(error.statusCode).json(serviceErrorToPayload(error));
}

return handleUnexpectedError(res, 'Error retrieving chat history', error, {
userId: req.body.user_id
userId: resolveChatbotUserId(req)
});
}
}

async function clearChatHistory(req, res) {
try {
const result = await chatbotService.clearChatHistory(req.body.user_id);
const userId = resolveChatbotUserId(req);
const result = await chatbotService.clearChatHistory(userId);
return res.status(result.statusCode).json(result.body);
} catch (error) {
if (isServiceError(error)) {
return res.status(error.statusCode).json(serviceErrorToPayload(error));
}

return handleUnexpectedError(res, 'Error clearing chat history', error, {
userId: req.body.user_id
userId: resolveChatbotUserId(req)
});
}
}
Expand Down
21 changes: 17 additions & 4 deletions controller/recipeController.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ const normalizeId = (id) => {
return id;
};

const resolveRecipeUserId = (req) => {
const requestUserId = req.body?.user_id || req.query?.user_id || req.params?.user_id;
const currentUserId = req.user?.userId;
const role = String(req.user?.role || '').toLowerCase();

if ((role === 'admin' || role === 'nutritionist') && requestUserId) {
return normalizeId(requestUserId);
}

return normalizeId(currentUserId);
};

async function enrichRecipeRow(recipe) {
if (!recipe) return null;

Expand Down Expand Up @@ -60,7 +72,6 @@ async function getRecipeDetailRow(recipeId) {

const createAndSaveRecipe = async (req, res) => {
const {
user_id,
ingredient_id,
ingredient_quantity,
recipe_name,
Expand All @@ -78,6 +89,7 @@ const createAndSaveRecipe = async (req, res) => {
return res.status(400).json({ errors: errors.array() });
}

const user_id = resolveRecipeUserId(req);
const recipe = await createRecipe.createRecipe(
user_id,
ingredient_id,
Expand Down Expand Up @@ -124,7 +136,7 @@ const createAndSaveRecipe = async (req, res) => {
};

const getRecipes = async (req, res) => {
const user_id = req.body.user_id;
const user_id = resolveRecipeUserId(req);

try {
if (!user_id) {
Expand Down Expand Up @@ -228,7 +240,7 @@ const getRecipes = async (req, res) => {

const getUserRecipes = async (req, res) => {
try {
let userId = req.params.user_id || req.query.user_id;
let userId = resolveRecipeUserId(req);
if (!userId) {
return res.status(400).json({ success: false, error: 'user_id is required' });
}
Expand Down Expand Up @@ -291,7 +303,8 @@ const getRecipeNutrition = async (req, res) => {
};

const deleteRecipe = async (req, res) => {
const { user_id, recipe_id } = req.body;
const user_id = resolveRecipeUserId(req);
const { recipe_id } = req.body;

try {
if (!user_id || !recipe_id) {
Expand Down
37 changes: 22 additions & 15 deletions controller/shoppingListController.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,22 @@ function sendWrapped(res, statusCode, body) {
});
}

function resolveShoppingListUserId(req) {
const requestUserId =
req.body?.user_id ||
req.body?.userId ||
req.query?.user_id ||
req.query?.userId;
const currentUserId = req.user?.userId;
const role = String(req.user?.role || '').toLowerCase();

if (role === 'admin' || role === 'nutritionist') {
return requestUserId ? normalizeId(requestUserId) : currentUserId;
}

return currentUserId;
}

async function getIngredientOptions(req, res) {
try {
const name = req.query?.name || '';
Expand All @@ -41,10 +57,7 @@ async function getIngredientOptions(req, res) {

async function generateFromMealPlan(req, res) {
try {
if (!req.body || !req.body.user_id) {
return res.status(400).json({ success: false, error: 'user_id required' });
}
const userId = normalizeId(req.body.user_id);
const userId = resolveShoppingListUserId(req);
const mealPlanIds = Array.isArray(req.body.meal_plan_ids) ? req.body.meal_plan_ids : [];
const result = await shoppingListService.generateFromMealPlan({ userId, mealPlanIds });
return sendWrapped(res, result.statusCode || 200, result.body || result);
Expand All @@ -55,10 +68,7 @@ async function generateFromMealPlan(req, res) {

async function createShoppingList(req, res) {
try {
if (!req.body || !req.body.user_id) {
return res.status(400).json({ success: false, error: 'user_id required' });
}
const userId = normalizeId(req.body.user_id);
const userId = resolveShoppingListUserId(req);
const result = await shoppingListService.createShoppingList({
userId,
name: req.body.name,
Expand All @@ -73,11 +83,7 @@ async function createShoppingList(req, res) {

async function getShoppingList(req, res) {
try {
const rawUserId = req.query?.user_id || req.query?.userId;
if (!rawUserId) {
return res.status(400).json({ success: false, error: 'user_id required' });
}
const userId = normalizeId(rawUserId);
const userId = resolveShoppingListUserId(req);
const result = await shoppingListService.getShoppingList(userId);
return sendWrapped(res, result.statusCode || 200, result.body || result);
} catch (error) {
Expand All @@ -92,7 +98,7 @@ async function updateShoppingListItem(req, res) {
return res.status(400).json({ success: false, error: 'id param required' });
}
const id = normalizeId(rawId);
const result = await shoppingListService.updateShoppingListItem(id, {
const result = await shoppingListService.updateShoppingListItem(id, req.user?.userId, {
purchased: req.body?.purchased,
quantity: req.body?.quantity,
notes: req.body?.notes
Expand All @@ -106,6 +112,7 @@ async function updateShoppingListItem(req, res) {
async function addShoppingListItem(req, res) {
try {
const result = await shoppingListService.addShoppingListItem({
userId: req.user?.userId,
shoppingListId: req.body?.shopping_list_id ? normalizeId(req.body.shopping_list_id) : undefined,
ingredientName: req.body?.ingredient_name,
category: req.body?.category,
Expand All @@ -129,7 +136,7 @@ async function deleteShoppingListItem(req, res) {
return res.status(400).json({ success: false, error: 'id param required' });
}
const id = normalizeId(rawId);
const result = await shoppingListService.deleteShoppingListItem(id);
const result = await shoppingListService.deleteShoppingListItem(id, req.user?.userId);
return sendWrapped(res, result.statusCode || 200, result.body || result);
} catch (error) {
return handleError(res, error, 'deleteShoppingListItem');
Expand Down
9 changes: 6 additions & 3 deletions model/appointmentModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ async function addAppointmentModelV2({

async function updateAppointmentModel(
id,
userId,
{
title,
doctor,
Expand Down Expand Up @@ -95,26 +96,28 @@ async function updateAppointmentModel(
reminder,
})
.eq("id", id)
.eq("user_id", userId)
.select()
.single();

if (error) throw error;
if (error && error.code !== "PGRST116") throw error;
return data;
} catch (err) {
throw err;
}
}

async function deleteAppointmentById(id) {
async function deleteAppointmentById(id, userId) {
try {
const { data, error } = await supabase
.from("appointments")
.delete()
.eq("id", id)
.eq("user_id", userId)
.select()
.single();

if (error) throw error;
if (error && error.code !== "PGRST116") throw error;
return data;
} catch (err) {
throw err;
Expand Down
5 changes: 3 additions & 2 deletions routes/account.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const express = require('express');
const router = express.Router();
const controller = require("../controller/accountController");
const { authenticateToken } = require('../middleware/authenticateToken');

router.route('/').get(controller.getAllAccount);
router.route('/').get(authenticateToken, controller.getAllAccount);

module.exports = router;
module.exports = router;
Loading
Loading