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
1 change: 0 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions src/app.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
const express = require('express');
const Sentry = require('@sentry/node');
const testRoutes = require('./routes/testRoutes');

Check warning on line 3 in src/app.js

View workflow job for this annotation

GitHub Actions / Lint Check

There should be no empty line between import groups

const app = express();
const logger = require('./startup/logger');
const globalErrorHandler = require('./utilities/errorHandling/globalErrorHandler');

Check warning on line 7 in src/app.js

View workflow job for this annotation

GitHub Actions / Lint Check

There should be no empty line between import groups
// const experienceRoutes = require('./routes/applicantAnalyticsRoutes');

// 1. Core initialization
Expand All @@ -15,20 +15,21 @@
require('./startup/compression')(app);
require('./startup/cors')(app);
require('./startup/bodyParser')(app); // <--- Crucial this runs before routes
require('./startup/session')(app);
require('./startup/session')(app); // Add session before middleware and routes

// 3. Define Routes (The "Destination")
// It is better to move these INSIDE startup/routes.js, but if they stay here:
app.use('/api/test', testRoutes);

const helpFeedbackRouter = require('./routes/helpFeedbackRouter');
const helpRequestRouter = require('./routes/helpRequestRouter');

app.use('/api/feedback', helpFeedbackRouter);
app.use('/api/helprequest', helpRequestRouter);

require('./startup/middleware')(app);
// This handles all other routes and likely has your 404 handler
require('./startup/routes')(app);
require('./startup/routes')(app);

// 4. Error Handling (The "Safety Net")
app.use(Sentry.Handlers.errorHandler());
Expand Down
37 changes: 37 additions & 0 deletions src/controllers/kitchenandinventory/KIInventoryController.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const KIInventoryController = () => {
const items = await KIInventoryItem.find(null, { __v: 0 }).lean().sort({ createdAt: -1 });
res.status(200).json({ message: 'All Items fetched successfully.', data: items });
} catch (err) {
console.error(err);
res.status(400).json({ message: 'Something went wrong while fetching items.' });
}
};
Expand All @@ -59,6 +60,7 @@ const KIInventoryController = () => {
.sort({ createdAt: -1 });
res.status(200).json({ message: 'Items fetched successfully.', data: items });
} catch (err) {
console.error(err);
res.status(400).json({ message: 'Something went wrong while fetching items.' });
}
};
Expand All @@ -74,6 +76,7 @@ const KIInventoryController = () => {
.sort({ presentQuantity: -1 });
res.status(200).json({ message: 'Preserved stock items fetched successfully.', data: items });
} catch (err) {
console.error(err);
res
.status(400)
.json({ message: 'Something went wrong while fetching preserved stock items.' });
Expand Down Expand Up @@ -154,6 +157,39 @@ const KIInventoryController = () => {
res.status(400).json({ message: err.message });
}
};
const getInventoryStats = async (req, res) => {
try {
// Only fetch the fields needed for stats — avoids sending full item payloads
const items = await KIInventoryItem.find(
{},
{ presentQuantity: 1, reorderAt: 1, category: 1, expiryDate: 1 },
).lean();
const totalItems = items.length;
const criticalStock = items.filter((i) => i.presentQuantity <= i.reorderAt * 0.5).length;
const lowStock = items.filter(
(i) => i.presentQuantity <= i.reorderAt && i.presentQuantity > i.reorderAt * 0.5,
).length;

const oneYearFromNow = new Date();
oneYearFromNow.setFullYear(oneYearFromNow.getFullYear() + 1);
const preserved = items.filter(
(i) => i.category === 'INGREDIENT' && new Date(i.expiryDate) >= oneYearFromNow,
).length;

res.status(200).json({
message: 'Inventory stats fetched successfully.',
data: {
totalItems,
criticalStock,
lowStock,
preserved,
},
});
} catch (err) {
console.error(err);
res.status(500).json({ message: 'Something went wrong while fetching inventory stats.' });
}
};
return {
addItem,
getItems,
Expand All @@ -162,6 +198,7 @@ const KIInventoryController = () => {
updateOnUsage,
updateStoredQuantity,
updateNextHarvest,
getInventoryStats,
};
};
module.exports = KIInventoryController;
2 changes: 1 addition & 1 deletion src/models/userTask.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const mongoose = require('mongoose');
const userTaskSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true, unique: true },
role: { type: String, enum: ['student', 'educator','support'], required: true },
role: { type: String, enum: ['student', 'educator', 'support'], required: true },
// Add 'support' role
});

Expand Down
7 changes: 3 additions & 4 deletions src/routes/activityLogRouter.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
const express = require('express');

const activityLogRouter = express.Router();
// Invoke the controller factory
const controller = require('../controllers/activityLogController')();

activityLogRouter
.route('/:studentId')
.get(controller.fetchSupportDailyLog);
activityLogRouter.route('/:studentId').get(controller.fetchSupportDailyLog);

// Export the INSTANCE
module.exports = activityLogRouter;
module.exports = activityLogRouter;
25 changes: 16 additions & 9 deletions src/routes/kitchenandinventory/KIInventoryRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,23 @@ const controller = require('../../controllers/kitchenandinventory/KIInventoryCon

const router = function () {
const inventoryRouter = express.Router();
// Routes for inventory items
inventoryRouter.route('/items').post(controller.addItem); // Route to add a new inventory item
inventoryRouter.route('/items').get(controller.getItems); // Route to get all inventory items
inventoryRouter.route('/items/:category').get(controller.getItemsByCategory); // Route to get items by category
inventoryRouter.route('/items/ingredients/preserved').get(controller.getPreservedStock); // Route to get preserved items
// Below update endpoints are non-idempotent and meant to be used for specific actions
inventoryRouter.route('/items/usage').post(controller.updateOnUsage); // Route to update item on usage
inventoryRouter.route('/items/storedQuantity').post(controller.updateStoredQuantity); // Route to update stored quantity
inventoryRouter.route('/items/nextHarvest').put(controller.updateNextHarvest); // Route to update next harvest details

// ── Specific named routes (must come before /:category wildcard) ──────────
inventoryRouter.route('/items').get(controller.getItems); // Get all inventory items
inventoryRouter.route('/items').post(controller.addItem); // Add a new inventory item
inventoryRouter.route('/items/stats').get(controller.getInventoryStats); // Get total, critical & low stock counts
inventoryRouter.route('/items/ingredients/preserved').get(controller.getPreservedStock); // Get preserved items (expiry >= 1 yr)

// ── Update endpoints (non-idempotent, specific actions) ───────────────────
inventoryRouter.route('/items/usage').post(controller.updateOnUsage); // Update item on usage
inventoryRouter.route('/items/storedQuantity').post(controller.updateStoredQuantity); // Add new stock
inventoryRouter.route('/items/nextHarvest').put(controller.updateNextHarvest); // Update next harvest details

// ── Wildcard route (must be last to avoid shadowing named routes above) ───
inventoryRouter.route('/items/:category').get(controller.getItemsByCategory); // Get items by category

return inventoryRouter;
};

module.exports = router;

Loading
Loading