From e700e027c42d6ecc0e69172aa9ec375970464b5a Mon Sep 17 00:00:00 2001 From: acegoal07 <39467245+acegoal07@users.noreply.github.com> Date: Wed, 8 Jul 2026 11:58:52 +0100 Subject: [PATCH 1/8] initial --- .../controller/getRandomBonusChallenge.js | 9 ++- backend/endpoints/hpc/controller/addHpc.js | 19 ++++-- .../endpoints/hpc/controller/addHpcToPool.js | 48 +++++++++----- backend/endpoints/hpc/controller/deleteHpc.js | 16 +++-- .../endpoints/hpc/controller/getHpcById.js | 8 +-- .../endpoints/hpc/controller/getHpcByName.js | 10 +-- .../endpoints/hpc/controller/getHpcByPool.js | 11 +++- .../hpc/controller/getHpcNotInPool.js | 14 ++-- .../hpc/controller/removeHpcFromPool.js | 39 +++++++---- .../instruction/controller/addInstruction.js | 64 +++++++++---------- .../controller/deleteInstruction.js | 14 ++-- .../controller/getAllInstructionsData.js | 14 ++-- .../controller/getAllInstructionsOnly.js | 47 +++++++------- .../controller/getInstructionsAllById.js | 8 +-- .../controller/getInstructionsOnlyById.js | 8 +-- .../controller/updateInstruction.js | 8 +-- .../endpoints/method/controller/addMethod.js | 8 +-- .../method/controller/deleteMethod.js | 8 +-- .../method/controller/getMethodById.js | 8 +-- .../endpoints/method/controller/getMethods.js | 8 +-- .../method/controller/updateMethod.js | 16 ++--- .../endpoints/people/controller/addPeople.js | 12 ++-- .../people/controller/addPeopleToTeam.js | 24 +++---- .../people/controller/deletePeople.js | 6 ++ .../people/controller/getPeopleById.js | 8 +-- .../people/controller/getPeopleByName.js | 8 +-- .../people/controller/getPeopleByTeam.js | 8 +-- .../people/controller/getPeopleNotInTeam.js | 8 +-- .../pool/controller/addPoolToTeam.js | 50 +++++++++++---- .../endpoints/pool/controller/createPool.js | 10 ++- .../endpoints/pool/controller/deletePool.js | 22 +++++-- backend/endpoints/pool/controller/getPool.js | 18 ++++-- .../pool/controller/getPoolByCluster.js | 22 +++++-- .../pool/controller/getPoolsByTeam.js | 35 +++++----- .../pool/controller/getPoolsNotInTeam.js | 31 +++++---- .../pool/controller/removePoolFromTeam.js | 54 +++++++++++----- .../endpoints/report/controller/addReport.js | 40 ++++++------ .../controller/getDailyOverviewReport.js | 22 +++---- backend/services/cron/cron.js | 3 +- backend/services/dailyReport/dailyReport.js | 3 + frontend/app/components/ClusterSettings.jsx | 2 +- frontend/app/components/Form.jsx | 4 +- frontend/app/components/Options.jsx | 2 +- frontend/app/components/TeamsSettingsPage.jsx | 7 +- 44 files changed, 460 insertions(+), 324 deletions(-) diff --git a/backend/endpoints/bonusChallenge/controller/getRandomBonusChallenge.js b/backend/endpoints/bonusChallenge/controller/getRandomBonusChallenge.js index ad67ff4..bbcf0e5 100644 --- a/backend/endpoints/bonusChallenge/controller/getRandomBonusChallenge.js +++ b/backend/endpoints/bonusChallenge/controller/getRandomBonusChallenge.js @@ -9,11 +9,13 @@ module.exports = (db) => { */ return async (req, res) => { try { + // Check to see if the user gets a bonus question if (Math.random() >= 0.4) { return res.status(200).json({ success: true }); } - const bonusChallenge = await db + // Get a random bonus question from the database + const response = await db .collection('bonusChallenge') .aggregate([ { @@ -35,13 +37,14 @@ module.exports = (db) => { })) ); - if (!bonusChallenge) { + // Check if a bonus question got returned from the question + if (!response) { return res .status(404) .json({ success: false, error: 'No active bonus challenges found' }); } - return res.status(200).json({ success: true, body: bonusChallenge[0] }); + return res.status(200).json({ success: true, body: response[0] }); } catch (error) { return res.status(500).json({ success: false, error: error.message }); } diff --git a/backend/endpoints/hpc/controller/addHpc.js b/backend/endpoints/hpc/controller/addHpc.js index 930fb0a..e572896 100644 --- a/backend/endpoints/hpc/controller/addHpc.js +++ b/backend/endpoints/hpc/controller/addHpc.js @@ -15,25 +15,33 @@ module.exports = (db) => { // Check name if (!name) { - return res.status(400).json({ success: false, error: 'Missing hpc name' }); + return res.status(400).json({ success: false, error: 'Missing cluster name' }); + } + + if (typeof name !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The cluster name provided is not a string' }); } const sanitizedName = String(name).trim(); if (sanitizedName.length == 0) { - return res.status(400).json({ success: false, error: 'The name provided is empty' }); + return res + .status(400) + .json({ success: false, error: 'The cluster name provided is empty' }); } // Check if hpc already exists - const existingHpc = await db.collection('cluster').findOne({ + const existing = await db.collection('cluster').findOne({ name: { $regex: `^${sanitizedName}$`, $options: 'i' } }); - if (existingHpc) { - return res.status(409).json({ success: false, error: 'HPC already exits' }); + if (existing) { + return res.status(409).json({ success: false, error: 'Cluster already exits' }); } // Add it to the database @@ -44,6 +52,7 @@ module.exports = (db) => { }) .then((res) => res.insertedId.toString()); + // Populate the database with generic instructions and methods for the cluster templateIt(clusterId, db); return res.status(200).json({ success: true }); diff --git a/backend/endpoints/hpc/controller/addHpcToPool.js b/backend/endpoints/hpc/controller/addHpcToPool.js index 835d437..572e615 100644 --- a/backend/endpoints/hpc/controller/addHpcToPool.js +++ b/backend/endpoints/hpc/controller/addHpcToPool.js @@ -15,12 +15,14 @@ module.exports = (db) => { const { poolId } = req.body || {}; // Check id - if (!id) { - return res.status(400).json({ success: false, error: 'Missing cluster id' }); + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The cluster ID provided is not a string' }); } - if (!poolId) { - return res.status(400).json({ success: false, error: 'Missing pool id' }); + if (!id) { + return res.status(400).json({ success: false, error: 'Missing cluster ID' }); } const sanitizedId = String(id).trim(); @@ -28,43 +30,55 @@ module.exports = (db) => { if (sanitizedId.length === 0) { return res .status(400) - .json({ success: false, error: 'The cluster id provided is empty' }); + .json({ success: false, error: 'The cluster ID provided is empty' }); } - const sanitizedPoolId = String(poolId).trim(); + if (!ObjectId.isValid(sanitizedId)) { + return res.status(400).json({ success: false, error: 'Invalid cluster ID provided' }); + } - if (sanitizedPoolId.length === 0) { - return res.status(400).json({ success: false, error: 'The pool id provided is empty' }); + // Check pool id + if (typeof poolId !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The pool ID provided is not a string' }); } - if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid cluster id provided' }); + if (!poolId) { + return res.status(400).json({ success: false, error: 'Missing pool ID' }); + } + + const sanitizedPoolId = String(poolId).trim(); + + if (sanitizedPoolId.length === 0) { + return res.status(400).json({ success: false, error: 'The pool ID provided is empty' }); } if (!ObjectId.isValid(sanitizedPoolId)) { - return res.status(400).json({ success: false, error: 'Invalid pool id provided' }); + return res.status(400).json({ success: false, error: 'Invalid pool ID provided' }); } // Get the cluster - const results = await db.collection('cluster').findOne({ + const cluster = await db.collection('cluster').findOne({ _id: new ObjectId(sanitizedId) }); - if (!results) { + if (!cluster) { return res.status(404).json({ success: false, error: "Cluster doesn't exist" }); } - if (results.poolId === sanitizedPoolId) { + if (cluster.poolId === sanitizedPoolId) { return res .status(400) .json({ success: false, error: 'Cluster already assigned to pool' }); } - const poolResults = await db.collection('pool').findOne({ + // Get pool + const pool = await db.collection('pool').findOne({ _id: new ObjectId(sanitizedPoolId) }); - if (!poolResults) { + if (!pool) { return res.status(404).json({ success: false, error: "Pool doesn't exist" }); } @@ -81,7 +95,7 @@ module.exports = (db) => { success: true, body: { id: sanitizedId, - name: results.name, + name: cluster.name, poolId: sanitizedPoolId } }); diff --git a/backend/endpoints/hpc/controller/deleteHpc.js b/backend/endpoints/hpc/controller/deleteHpc.js index bba09a4..e285199 100644 --- a/backend/endpoints/hpc/controller/deleteHpc.js +++ b/backend/endpoints/hpc/controller/deleteHpc.js @@ -15,7 +15,13 @@ module.exports = (db) => { // Check id if (!id) { - return res.status(400).json({ success: false, error: 'Missing hpc id' }); + return res.status(400).json({ success: false, error: 'Missing cluster id' }); + } + + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The cluster id provided is not a string' }); } const sanitizedId = String(id).trim(); @@ -23,19 +29,19 @@ module.exports = (db) => { if (sanitizedId.length === 0) { return res .status(400) - .json({ success: false, error: "The hpc id you've provided is empty" }); + .json({ success: false, error: "The cluster id you've provided is empty" }); } if (!ObjectId.isValid(sanitizedId)) { return res.status(400).json({ success: false, error: 'Invalid cluster id provided' }); } - // Check cluster exists - const existingCluster = await db.collection('cluster').findOneAndDelete({ + // Get cluster + const cluster = await db.collection('cluster').findOneAndDelete({ _id: new ObjectId(sanitizedId) }); - if (!existingCluster) { + if (!cluster) { return res.status(409).json({ success: false, error: "HPC doesn't exists" diff --git a/backend/endpoints/hpc/controller/getHpcById.js b/backend/endpoints/hpc/controller/getHpcById.js index 6755c5b..d3d9f33 100644 --- a/backend/endpoints/hpc/controller/getHpcById.js +++ b/backend/endpoints/hpc/controller/getHpcById.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id } = req.params || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing cluster id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The cluster id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing cluster id' }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { diff --git a/backend/endpoints/hpc/controller/getHpcByName.js b/backend/endpoints/hpc/controller/getHpcByName.js index 938c954..6afe8e3 100644 --- a/backend/endpoints/hpc/controller/getHpcByName.js +++ b/backend/endpoints/hpc/controller/getHpcByName.js @@ -12,14 +12,14 @@ module.exports = (db) => { const { name } = req.params || {}; // Check name + if (!name) { + return res.status(400).json({ success: false, error: 'Missing cluster name' }); + } + if (typeof name !== 'string') { return res .status(400) - .json({ success: false, error: 'The name provided is not a string' }); - } - - if (!name) { - return res.status(400).json({ success: false, error: 'Missing cluster name' }); + .json({ success: false, error: 'The cluster name provided is not a string' }); } const sanitizedName = String(name).trim(); diff --git a/backend/endpoints/hpc/controller/getHpcByPool.js b/backend/endpoints/hpc/controller/getHpcByPool.js index c267562..d8ead17 100644 --- a/backend/endpoints/hpc/controller/getHpcByPool.js +++ b/backend/endpoints/hpc/controller/getHpcByPool.js @@ -13,10 +13,17 @@ module.exports = (db) => { try { const { id } = req.params || {}; + // Check id if (!id) { return res.status(400).json({ success: false, error: 'Missing pool id' }); } + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The pool id provided is not a string' }); + } + const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { @@ -28,7 +35,7 @@ module.exports = (db) => { } // Get the cluster - const data = await db + const respone = await db .collection('cluster') .find({ poolId: sanitizedId @@ -41,7 +48,7 @@ module.exports = (db) => { })) ); - return res.status(200).json({ success: true, body: data }); + return res.status(200).json({ success: true, body: respone }); } catch (error) { return res.status(500).json({ success: false, error: error.message }); } diff --git a/backend/endpoints/hpc/controller/getHpcNotInPool.js b/backend/endpoints/hpc/controller/getHpcNotInPool.js index 3714368..9efeda3 100644 --- a/backend/endpoints/hpc/controller/getHpcNotInPool.js +++ b/backend/endpoints/hpc/controller/getHpcNotInPool.js @@ -14,14 +14,14 @@ module.exports = (db) => { const { id } = req.params || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing pool id' }); + } + if (typeof id !== 'string') { return res .status(400) - .json({ success: false, error: 'The team id provided is not a string' }); - } - - if (!id) { - return res.status(400).json({ success: false, error: 'Missing pool id' }); + .json({ success: false, error: 'The pool id provided is not a string' }); } const sanitizedId = String(id).trim(); @@ -35,7 +35,7 @@ module.exports = (db) => { } // Get the cluster - const data = await db + const response = await db .collection('cluster') .find({ poolId: { $ne: sanitizedId } @@ -48,7 +48,7 @@ module.exports = (db) => { })) ); - return res.status(200).json({ success: true, body: data }); + return res.status(200).json({ success: true, body: response }); } catch (error) { return res.status(500).json({ success: false, error: error.message }); } diff --git a/backend/endpoints/hpc/controller/removeHpcFromPool.js b/backend/endpoints/hpc/controller/removeHpcFromPool.js index b0b041f..89b8773 100644 --- a/backend/endpoints/hpc/controller/removeHpcFromPool.js +++ b/backend/endpoints/hpc/controller/removeHpcFromPool.js @@ -19,8 +19,10 @@ module.exports = (db) => { return res.status(400).json({ success: false, error: 'Missing cluster id' }); } - if (!poolId) { - return res.status(400).json({ success: false, error: 'Missing pool id' }); + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The cluster id provided is not a string' }); } const sanitizedId = String(id).trim(); @@ -31,41 +33,54 @@ module.exports = (db) => { .json({ success: false, error: 'The cluster id provided is empty' }); } + if (!ObjectId.isValid(sanitizedId)) { + return res.status(400).json({ success: false, error: 'Invalid cluster id provided' }); + } + + // Check pool id + if (!poolId) { + return res.status(400).json({ success: false, error: 'Missing pool id' }); + } + + if (typeof poolId !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The pool id provided is not a string' }); + } + const sanitizedPoolId = String(poolId).trim(); if (sanitizedPoolId.length === 0) { return res.status(400).json({ success: false, error: 'The pool id provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid cluster id provided' }); - } - if (!ObjectId.isValid(sanitizedPoolId)) { return res.status(400).json({ success: false, error: 'Invalid pool id provided' }); } // Get the cluster - const results = await db.collection('cluster').findOne({ + const cluster = await db.collection('cluster').findOne({ _id: new ObjectId(sanitizedId) }); - if (!results) { + if (!cluster) { return res.status(404).json({ success: false, error: "Cluster doesn't exist" }); } - const poolResults = await db.collection('pool').findOne({ + // Get the pool + const pool = await db.collection('pool').findOne({ _id: new ObjectId(sanitizedPoolId) }); - if (!poolResults) { + if (!pool) { return res.status(404).json({ success: false, error: "Pool doesn't exist" }); } - if (!results.poolId === sanitizedPoolId) { + if (!cluster.poolId === sanitizedPoolId) { return res.status(400).json({ success: false, error: 'Cluster not assigned to pool' }); } + // Update database db.collection('cluster').updateOne( { _id: new ObjectId(sanitizedId) }, { @@ -79,7 +94,7 @@ module.exports = (db) => { success: true, body: { id: sanitizedId, - name: results.name + name: cluster.name } }); } catch (error) { diff --git a/backend/endpoints/instruction/controller/addInstruction.js b/backend/endpoints/instruction/controller/addInstruction.js index d389f75..475799a 100644 --- a/backend/endpoints/instruction/controller/addInstruction.js +++ b/backend/endpoints/instruction/controller/addInstruction.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { title, expectedTime, description, clusterId, good, bad } = req.body || {}; // Check title + if (!title) { + return res.status(400).json({ success: false, error: 'Missing instruction title' }); + } + if (typeof title !== 'string') { return res .status(400) .json({ success: false, error: 'The title provided is not a string' }); } - if (!title) { - return res.status(400).json({ success: false, error: 'Missing instruction title' }); - } - const sanitizedTitle = String(title).trim(); if (sanitizedTitle.length == 0) { @@ -31,16 +31,16 @@ module.exports = (db) => { } // Check expected time + if (!expectedTime) { + return res.status(400).json({ success: false, error: 'Missing expected time' }); + } + if (typeof expectedTime !== 'string') { return res .status(400) .json({ success: false, error: 'The expected time provided is not a string' }); } - if (!expectedTime) { - return res.status(400).json({ success: false, error: 'Missing expected time' }); - } - const sanitizedExpectedTime = String(expectedTime).trim(); if (sanitizedExpectedTime.length == 0) { @@ -50,16 +50,16 @@ module.exports = (db) => { } // Check description + if (!description) { + return res.status(400).json({ success: false, error: 'Missing description' }); + } + if (typeof description !== 'string') { return res .status(400) .json({ success: false, error: 'The description provided is not a string' }); } - if (!description) { - return res.status(400).json({ success: false, error: 'Missing description' }); - } - const sanitizedDescription = String(description).trim(); if (sanitizedDescription.length == 0) { @@ -69,16 +69,16 @@ module.exports = (db) => { } // Check cluster id + if (!clusterId) { + return res.status(400).json({ success: false, error: 'Missing cluster id' }); + } + if (typeof clusterId !== 'string') { return res .status(400) .json({ success: false, error: 'The cluster id provided is not a string' }); } - if (!clusterId) { - return res.status(400).json({ success: false, error: 'Missing cluster id' }); - } - const sanitizedClusterId = String(clusterId).trim(); if (sanitizedClusterId.length == 0) { @@ -92,16 +92,16 @@ module.exports = (db) => { } // Check good + if (!good) { + return res.status(400).json({ success: false, error: 'Missing instruction title' }); + } + if (typeof good !== 'string') { return res .status(400) .json({ success: false, error: 'The good provided is not a string' }); } - if (!good) { - return res.status(400).json({ success: false, error: 'Missing instruction title' }); - } - const sanitizedGood = String(good).trim(); if (sanitizedGood.length == 0) { @@ -109,33 +109,28 @@ module.exports = (db) => { } // Check bad + if (!bad) { + return res.status(400).json({ success: false, error: 'Missing instruction title' }); + } + if (typeof bad !== 'string') { return res .status(400) .json({ success: false, error: 'The bad provided is not a string' }); } - if (!bad) { - return res.status(400).json({ success: false, error: 'Missing instruction title' }); - } - const sanitizedBad = String(bad).trim(); if (sanitizedBad.length == 0) { return res.status(400).json({ success: false, error: 'The bad provided is empty' }); } - // Get new instructions position - const currentTotalInstructions = await db - .collection('instruction') - .countDocuments({ clusterId: sanitizedClusterId }); - - // Check if cluster exists - const clusterExists = await db.collection('cluster').findOne({ + // Get cluster + const cluster = await db.collection('cluster').findOne({ _id: new ObjectId(sanitizedClusterId) }); - if (!clusterExists) { + if (!cluster) { return res .status(404) .json({ success: false, error: 'The cluster specified does not exits' }); @@ -149,7 +144,10 @@ module.exports = (db) => { clusterId: sanitizedClusterId, good: sanitizedGood, bad: sanitizedBad, - position: currentTotalInstructions + 1 + position: + (await db + .collection('instruction') + .countDocuments({ clusterId: sanitizedClusterId })) + 1 }); return res.status(200).json({ success: true }); diff --git a/backend/endpoints/instruction/controller/deleteInstruction.js b/backend/endpoints/instruction/controller/deleteInstruction.js index 9ff9b09..519c345 100644 --- a/backend/endpoints/instruction/controller/deleteInstruction.js +++ b/backend/endpoints/instruction/controller/deleteInstruction.js @@ -14,24 +14,24 @@ module.exports = (db) => { const { id } = req.params; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing instruction ID' }); + } + if (typeof id !== 'string') { return res .status(400) - .json({ success: false, error: 'The instruction id provided is not a string' }); - } - - if (!id) { - return res.status(400).json({ success: false, error: 'Missing instruction id' }); + .json({ success: false, error: 'The instruction ID provided is not a string' }); } const sanitizedId = String(id).trim(); if (sanitizedId.length == 0) { - return res.status(400).json({ success: false, error: 'The id provided is empty' }); + return res.status(400).json({ success: false, error: 'The ID provided is empty' }); } if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'The id provided is invalid' }); + return res.status(400).json({ success: false, error: 'The ID provided is invalid' }); } // Delete instruction diff --git a/backend/endpoints/instruction/controller/getAllInstructionsData.js b/backend/endpoints/instruction/controller/getAllInstructionsData.js index 9b162ad..7d92c94 100644 --- a/backend/endpoints/instruction/controller/getAllInstructionsData.js +++ b/backend/endpoints/instruction/controller/getAllInstructionsData.js @@ -14,14 +14,14 @@ module.exports = (db) => { const { id } = req.params || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing cluster ID' }); + } + if (typeof id !== 'string') { return res .status(400) - .json({ success: false, error: 'The cluster id provided is not a string' }); - } - - if (!id) { - return res.status(400).json({ success: false, error: 'Missing cluster id' }); + .json({ success: false, error: 'The cluster ID provided is not a string' }); } const sanitizedId = String(id).trim(); @@ -29,11 +29,11 @@ module.exports = (db) => { if (sanitizedId.length === 0) { return res .status(400) - .json({ success: false, error: 'The cluster id provided is empty' }); + .json({ success: false, error: 'The cluster ID provided is empty' }); } if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid cluster id provided' }); + return res.status(400).json({ success: false, error: 'Invalid cluster ID provided' }); } const response = []; diff --git a/backend/endpoints/instruction/controller/getAllInstructionsOnly.js b/backend/endpoints/instruction/controller/getAllInstructionsOnly.js index 9953088..f1fa052 100644 --- a/backend/endpoints/instruction/controller/getAllInstructionsOnly.js +++ b/backend/endpoints/instruction/controller/getAllInstructionsOnly.js @@ -14,14 +14,14 @@ module.exports = (db) => { const { id } = req.params || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing cluster ID' }); + } + if (typeof id !== 'string') { return res .status(400) - .json({ success: false, error: 'The cluster id provided is not a string' }); - } - - if (!id) { - return res.status(400).json({ success: false, error: 'Missing cluster id' }); + .json({ success: false, error: 'The cluster ID provided is not a string' }); } const sanitizedId = String(id).trim(); @@ -29,30 +29,31 @@ module.exports = (db) => { if (sanitizedId.length === 0) { return res .status(400) - .json({ success: false, error: 'The cluster id provided is empty' }); + .json({ success: false, error: 'The cluster Id provided is empty' }); } if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid cluster id provided' }); + return res.status(400).json({ success: false, error: 'Invalid cluster ID provided' }); } // Get all the instructions - const response = await db - .collection('instruction') - .find({ - clusterId: sanitizedId - }) - .toArray() - .then((res) => - res.map(({ _id, ...rest }) => ({ - id: _id.toString(), - ...rest - })) - ); - - return res - .status(200) - .json({ success: true, body: response.sort((a, b) => a.position - b.position) }); + return res.status(200).json({ + success: true, + body: await db + .collection('instruction') + .find({ + clusterId: sanitizedId + }) + .toArray() + .then((res) => + res + .map(({ _id, ...rest }) => ({ + id: _id.toString(), + ...rest + })) + .sort((a, b) => a.position - b.position) + ) + }); } catch (error) { return res.status(500).json({ success: false, error: error.message }); } diff --git a/backend/endpoints/instruction/controller/getInstructionsAllById.js b/backend/endpoints/instruction/controller/getInstructionsAllById.js index 5712774..5dd1399 100644 --- a/backend/endpoints/instruction/controller/getInstructionsAllById.js +++ b/backend/endpoints/instruction/controller/getInstructionsAllById.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id } = req.params || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing instruction id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The instruction id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing instruction id' }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { diff --git a/backend/endpoints/instruction/controller/getInstructionsOnlyById.js b/backend/endpoints/instruction/controller/getInstructionsOnlyById.js index 3b787da..fb1ecf5 100644 --- a/backend/endpoints/instruction/controller/getInstructionsOnlyById.js +++ b/backend/endpoints/instruction/controller/getInstructionsOnlyById.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id } = req.params || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing instruction id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The instruction id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing instruction id' }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { diff --git a/backend/endpoints/instruction/controller/updateInstruction.js b/backend/endpoints/instruction/controller/updateInstruction.js index ca93935..f2bd771 100644 --- a/backend/endpoints/instruction/controller/updateInstruction.js +++ b/backend/endpoints/instruction/controller/updateInstruction.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id, ...rest } = req.body || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing instruction id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The instruction provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing instruction id' }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length == 0) { diff --git a/backend/endpoints/method/controller/addMethod.js b/backend/endpoints/method/controller/addMethod.js index 27a35e2..21946e1 100644 --- a/backend/endpoints/method/controller/addMethod.js +++ b/backend/endpoints/method/controller/addMethod.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id, content } = req.body || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing instruction id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The instruction id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing instruction id' }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { diff --git a/backend/endpoints/method/controller/deleteMethod.js b/backend/endpoints/method/controller/deleteMethod.js index 04597fb..3016dfd 100644 --- a/backend/endpoints/method/controller/deleteMethod.js +++ b/backend/endpoints/method/controller/deleteMethod.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id } = req.params; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing method id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The method id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing method id' }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { diff --git a/backend/endpoints/method/controller/getMethodById.js b/backend/endpoints/method/controller/getMethodById.js index e8c4903..93eb706 100644 --- a/backend/endpoints/method/controller/getMethodById.js +++ b/backend/endpoints/method/controller/getMethodById.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id } = req.params || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing method id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The method id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing method id' }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { diff --git a/backend/endpoints/method/controller/getMethods.js b/backend/endpoints/method/controller/getMethods.js index d07953f..5b80c8b 100644 --- a/backend/endpoints/method/controller/getMethods.js +++ b/backend/endpoints/method/controller/getMethods.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id } = req.params || {}; // check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing instruction id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The instruction id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing instruction id' }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { diff --git a/backend/endpoints/method/controller/updateMethod.js b/backend/endpoints/method/controller/updateMethod.js index 5ec5a9c..2ec7b3a 100644 --- a/backend/endpoints/method/controller/updateMethod.js +++ b/backend/endpoints/method/controller/updateMethod.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id, content } = req.body; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing method id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The method id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing method id' }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { @@ -37,16 +37,16 @@ module.exports = (db) => { } // Check content + if (!content) { + return res.status(400).json({ success: false, error: 'Missing method content' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The content provided is not a string' }); } - if (!content) { - return res.status(400).json({ success: false, error: 'Missing method content' }); - } - const sanitizedContent = String(content).trim(); if (sanitizedContent.length == 0) { diff --git a/backend/endpoints/people/controller/addPeople.js b/backend/endpoints/people/controller/addPeople.js index f61d369..97606fb 100644 --- a/backend/endpoints/people/controller/addPeople.js +++ b/backend/endpoints/people/controller/addPeople.js @@ -12,16 +12,16 @@ module.exports = (db) => { const { name } = req.body || {}; // Check name + if (!name) { + return res.status(400).json({ success: false, error: 'Missing the persons name' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The name provided is not a string' }); } - if (!name) { - return res.status(400).json({ success: false, error: 'Missing the persons name' }); - } - const sanitizedName = String(name).trim(); if (sanitizedName.length === 0) { @@ -29,14 +29,14 @@ module.exports = (db) => { } // Make sure the person exists - const existingPerson = await db.collection('person').findOne({ + const person = await db.collection('person').findOne({ name: { $regex: `^${sanitizedName}$`, $options: 'i' } }); - if (existingPerson) { + if (person) { return res.status(409).json({ success: false, error: 'Person already exits' }); } diff --git a/backend/endpoints/people/controller/addPeopleToTeam.js b/backend/endpoints/people/controller/addPeopleToTeam.js index 4739e38..0750227 100644 --- a/backend/endpoints/people/controller/addPeopleToTeam.js +++ b/backend/endpoints/people/controller/addPeopleToTeam.js @@ -15,16 +15,16 @@ module.exports = (db) => { const { teamId } = req.body || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: "Missing person's id" }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The persons id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: "Missing person's id" }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { @@ -38,16 +38,16 @@ module.exports = (db) => { } // Check team id + if (!teamId) { + return res.status(400).json({ success: false, error: "Missing team's id" }); + } + if (typeof teamId !== 'string') { return res .status(400) .json({ success: false, error: 'The team id provided is not a string' }); } - if (!teamId) { - return res.status(400).json({ success: false, error: "Missing team's id" }); - } - const sanitizedTeamId = String(teamId).trim(); if (sanitizedTeamId.length === 0) { @@ -61,18 +61,18 @@ module.exports = (db) => { } // Check if the person exists - const personExists = await db.collection('person').findOne({ + const person = await db.collection('person').findOne({ _id: new ObjectId(sanitizedId) }); - if (!personExists) { + if (!person) { return res.status(404).json({ success: false, error: "Person doesn't exist" }); } // Check if clusters current team wont be left without clusters - if (personExists.teamId) { + if (person.teamId) { const cluster_count = await db.collection('cluster').countDocuments({ - teamId: personExists.teamId + teamId: person.teamId }); if (cluster_count <= 1) { diff --git a/backend/endpoints/people/controller/deletePeople.js b/backend/endpoints/people/controller/deletePeople.js index fa31fa0..67e81f2 100644 --- a/backend/endpoints/people/controller/deletePeople.js +++ b/backend/endpoints/people/controller/deletePeople.js @@ -18,6 +18,12 @@ module.exports = (db) => { return res.status(400).json({ success: false, error: 'Missing persons id' }); } + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The persons id provided is not a string' }); + } + if (!ObjectId.isValid(id)) { return res.status(400).json({ success: false, error: 'Invalid person id provided' }); } diff --git a/backend/endpoints/people/controller/getPeopleById.js b/backend/endpoints/people/controller/getPeopleById.js index 6bc9be3..2c94f18 100644 --- a/backend/endpoints/people/controller/getPeopleById.js +++ b/backend/endpoints/people/controller/getPeopleById.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id } = req.params || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing persons id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The persons id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing persons id' }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { diff --git a/backend/endpoints/people/controller/getPeopleByName.js b/backend/endpoints/people/controller/getPeopleByName.js index 3a20342..3ad0788 100644 --- a/backend/endpoints/people/controller/getPeopleByName.js +++ b/backend/endpoints/people/controller/getPeopleByName.js @@ -12,16 +12,16 @@ module.exports = (db) => { const { name } = req.params || {}; // Check name + if (!name) { + return res.status(400).json({ success: false, error: 'Missing persons name' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The persons name provided is not a string' }); } - if (!name) { - return res.status(400).json({ success: false, error: 'Missing persons name' }); - } - const sanitizedName = String(name).trim(); if (sanitizedName.length == 0) { diff --git a/backend/endpoints/people/controller/getPeopleByTeam.js b/backend/endpoints/people/controller/getPeopleByTeam.js index ebe6760..393c2bf 100644 --- a/backend/endpoints/people/controller/getPeopleByTeam.js +++ b/backend/endpoints/people/controller/getPeopleByTeam.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id } = req.params || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing team id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The team id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing team id' }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { diff --git a/backend/endpoints/people/controller/getPeopleNotInTeam.js b/backend/endpoints/people/controller/getPeopleNotInTeam.js index 09189f0..b724cb8 100644 --- a/backend/endpoints/people/controller/getPeopleNotInTeam.js +++ b/backend/endpoints/people/controller/getPeopleNotInTeam.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id } = req.params || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing team id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The team id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing team id' }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { diff --git a/backend/endpoints/pool/controller/addPoolToTeam.js b/backend/endpoints/pool/controller/addPoolToTeam.js index 3fc03f3..1c31072 100644 --- a/backend/endpoints/pool/controller/addPoolToTeam.js +++ b/backend/endpoints/pool/controller/addPoolToTeam.js @@ -14,53 +14,75 @@ module.exports = (db) => { const { teamId } = req.body || {}; const { id } = req.params || {}; + // Check id if (!id) { return res.status(400).json({ success: false, error: 'missing pool ID' }); } - if (!teamId) { - return res.status(400).json({ success: false, error: 'missing team ID' }); + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The pool ID provided is not a string' }); } const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { - return res.status(400).json({ success: false, error: 'The pool id provided is empty' }); + return res.status(400).json({ success: false, error: 'The pool ID provided is empty' }); + } + + if (!ObjectId.isValid(sanitizedId)) { + return res.status(400).json({ success: false, error: 'Invalid pool ID provided' }); + } + + // Check team id + if (!teamId) { + return res.status(400).json({ success: false, error: 'missing team ID' }); + } + + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The team ID provided is not a string' }); } const sanitizedTeamId = String(teamId).trim(); if (sanitizedTeamId.length === 0) { - return res.status(400).json({ success: false, error: 'The team id provided is empty' }); + return res.status(400).json({ success: false, error: 'The team ID provided is empty' }); + } + + if (!ObjectId.isValid(sanitizedTeamId)) { + return res.status(400).json({ success: false, error: 'Invalid team ID provided' }); } - const poolResults = await db - .collection('pool') - .findOne({ _id: new ObjectId(sanitizedId) }); + // Get pool + const pool = await db.collection('pool').findOne({ _id: new ObjectId(sanitizedId) }); - if (!poolResults) { + if (!pool) { return res.status(404).json({ success: false, error: 'Pool with that ID not found' }); } - const teamResults = await db - .collection('team') - .findOne({ _id: new ObjectId(sanitizedTeamId) }); + // Get team + const team = await db.collection('team').findOne({ _id: new ObjectId(sanitizedTeamId) }); - if (!teamResults) { + if (!team) { return res.status(404).json({ success: false, error: 'Team with that ID not found' }); } - const teamPoolResults = await db.collection('teampool').findOne({ + // Team pool + const teamPool = await db.collection('teampool').findOne({ teamId: sanitizedTeamId, poolId: sanitizedId }); - if (teamPoolResults) { + if (teamPool) { return res .status(400) .json({ success: false, error: 'Pool is already assigned to team' }); } + // Add to database const result = await db.collection('teampool').insertOne({ teamId: sanitizedTeamId, poolId: sanitizedId diff --git a/backend/endpoints/pool/controller/createPool.js b/backend/endpoints/pool/controller/createPool.js index 2afd5b7..fbd7502 100644 --- a/backend/endpoints/pool/controller/createPool.js +++ b/backend/endpoints/pool/controller/createPool.js @@ -16,6 +16,12 @@ module.exports = (db) => { return res.status(400).json({ success: false, error: "Missing pool's name" }); } + if (typeof name !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The name provided is not a string' }); + } + const sanitizedName = String(name).trim(); if (sanitizedName.length === 0) { @@ -23,14 +29,14 @@ module.exports = (db) => { } // Make sure the person exists - const existingPerson = await db.collection('pool').findOne({ + const person = await db.collection('pool').findOne({ name: { $regex: `^${sanitizedName}$`, $options: 'i' } }); - if (existingPerson) { + if (person) { return res .status(409) .json({ success: false, error: 'Pool with this name already exits' }); diff --git a/backend/endpoints/pool/controller/deletePool.js b/backend/endpoints/pool/controller/deletePool.js index afa3930..433cbfd 100644 --- a/backend/endpoints/pool/controller/deletePool.js +++ b/backend/endpoints/pool/controller/deletePool.js @@ -15,16 +15,24 @@ module.exports = (db) => { // Check id if (!id) { - return res.status(400).json({ success: false, error: 'Missing pool id' }); + return res.status(400).json({ success: false, error: 'Missing pool ID' }); } - if (!ObjectId.isValid(id)) { - return res.status(400).json({ success: false, error: 'Invalid pool id provided' }); + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The pool ID provided is not a string' }); + } + + const sanitizedId = String(id).trim(); + + if (!ObjectId.isValid(sanitizedId)) { + return res.status(400).json({ success: false, error: 'Invalid pool ID provided' }); } // Check if pool exits const existingPerson = await db.collection('pool').findOne({ - _id: new ObjectId(id) + _id: new ObjectId(sanitizedId) }); if (!existingPerson) { @@ -36,7 +44,7 @@ module.exports = (db) => { // Check if pool has clusters const hasClusters = await db.collection('cluster').findOne({ - poolId: id + poolId: sanitizedId }); if (hasClusters) { @@ -47,7 +55,7 @@ module.exports = (db) => { // Check if pool is assigned to a team const isAssigned = await db.collection('teampool').findOne({ - poolId: id + poolId: sanitizedId }); if (isAssigned) { @@ -58,7 +66,7 @@ module.exports = (db) => { // Delete the pool from the database await db.collection('pool').deleteOne({ - _id: new ObjectId(id) + _id: new ObjectId(sanitizedId) }); return res.status(200).json({ success: true }); diff --git a/backend/endpoints/pool/controller/getPool.js b/backend/endpoints/pool/controller/getPool.js index 07760b6..803bc2b 100644 --- a/backend/endpoints/pool/controller/getPool.js +++ b/backend/endpoints/pool/controller/getPool.js @@ -15,25 +15,31 @@ module.exports = (db) => { // Check id if (!id) { - return res.status(400).json({ success: false, error: 'Missing pool id' }); + return res.status(400).json({ success: false, error: 'Missing pool ID' }); + } + + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The pool ID provided is not a string' }); } const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { - return res.status(400).json({ success: false, error: 'The id provided is empty' }); + return res.status(400).json({ success: false, error: 'The pool ID provided is empty' }); } if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid pool id provided' }); + return res.status(400).json({ success: false, error: 'Invalid pool ID provided' }); } // Get the pool from the database - const results = await db.collection('pool').findOne({ + const pool = await db.collection('pool').findOne({ _id: new ObjectId(sanitizedId) }); - if (!results) { + if (!pool) { return res.status(404).json({ success: false, error: "Pool doesn't exist" }); } @@ -41,7 +47,7 @@ module.exports = (db) => { success: true, body: { id: sanitizedId, - name: results.name + name: pool.name } }); } catch (error) { diff --git a/backend/endpoints/pool/controller/getPoolByCluster.js b/backend/endpoints/pool/controller/getPoolByCluster.js index 48566d5..0c92e93 100644 --- a/backend/endpoints/pool/controller/getPoolByCluster.js +++ b/backend/endpoints/pool/controller/getPoolByCluster.js @@ -15,29 +15,37 @@ module.exports = (db) => { // Check id if (!id) { - return res.status(400).json({ success: false, error: 'Missing cluster id' }); + return res.status(400).json({ success: false, error: 'Missing cluster ID' }); + } + + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The cluster ID provided is not a string' }); } const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { - return res.status(400).json({ success: false, error: 'The id provided is empty' }); + return res + .status(400) + .json({ success: false, error: 'The cluster ID provided is empty' }); } if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid cluster id provided' }); + return res.status(400).json({ success: false, error: 'Invalid cluster ID provided' }); } // Get the cluster from the database - const results = await db.collection('cluster').findOne({ + const cluster = await db.collection('cluster').findOne({ _id: new ObjectId(sanitizedId) }); - if (!results) { + if (!cluster) { return res.status(404).json({ success: false, error: "Cluster doesn't exist" }); } - if (!results.poolId) { + if (!cluster.poolId) { return res.status(404).json({ success: false, error: 'Cluster not assigned to pool' }); } @@ -45,7 +53,7 @@ module.exports = (db) => { success: true, body: { id: sanitizedId, - pool: results.poolId + pool: cluster.poolId } }); } catch (error) { diff --git a/backend/endpoints/pool/controller/getPoolsByTeam.js b/backend/endpoints/pool/controller/getPoolsByTeam.js index fd96dcd..3023376 100644 --- a/backend/endpoints/pool/controller/getPoolsByTeam.js +++ b/backend/endpoints/pool/controller/getPoolsByTeam.js @@ -15,25 +15,31 @@ module.exports = (db) => { // Check id if (!id) { - return res.status(400).json({ success: false, error: 'Missing team id' }); + return res.status(400).json({ success: false, error: 'Missing team ID' }); + } + + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The team ID provided is not a string' }); } const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { - return res.status(400).json({ success: false, error: 'The team id provided is empty' }); + return res.status(400).json({ success: false, error: 'The team ID provided is empty' }); } if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid team id provided' }); + return res.status(400).json({ success: false, error: 'Invalid team ID provided' }); } - const poolResults = await db.collection('team').findOne({ + const pool = await db.collection('team').findOne({ _id: new ObjectId(sanitizedId) }); - if (!poolResults) { - return res.status(404).json({ success: false, error: "team doesn't exist" }); + if (!pool) { + return res.status(404).json({ success: false, error: "Team doesn't exist" }); } // Get the teamPool @@ -43,23 +49,18 @@ module.exports = (db) => { return res.status(404).json({ success: false, error: 'Team does not have any pools' }); } - // Get all pool IDs - const poolIds = teamPools.map((tp) => new ObjectId(tp.poolId)); - // Fetch all pool documents - const pools = await db + const allPools = await db .collection('pool') - .find({ _id: { $in: poolIds } }) + .find({ _id: { $in: teamPools.map((tp) => new ObjectId(tp.poolId)) } }) .toArray(); - const response = pools.map(({ _id, ...pool }) => ({ - id: _id, - ...pool - })); - return res.json({ success: true, - body: response + body: allPools.map(({ _id, ...pool }) => ({ + id: _id, + ...pool + })) }); } catch (error) { return res.status(500).json({ success: false, error: error.message }); diff --git a/backend/endpoints/pool/controller/getPoolsNotInTeam.js b/backend/endpoints/pool/controller/getPoolsNotInTeam.js index 7dd2b9b..af13fc4 100644 --- a/backend/endpoints/pool/controller/getPoolsNotInTeam.js +++ b/backend/endpoints/pool/controller/getPoolsNotInTeam.js @@ -15,25 +15,32 @@ module.exports = (db) => { // Check id if (!id) { - return res.status(400).json({ success: false, error: 'Missing team id' }); + return res.status(400).json({ success: false, error: 'Missing team ID' }); + } + + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The team ID provided is not a string' }); } const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { - return res.status(400).json({ success: false, error: 'The team id provided is empty' }); + return res.status(400).json({ success: false, error: 'The team ID provided is empty' }); } if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid team id provided' }); + return res.status(400).json({ success: false, error: 'Invalid team ID provided' }); } - const poolResults = await db.collection('team').findOne({ + // Get pool + const pool = await db.collection('team').findOne({ _id: new ObjectId(sanitizedId) }); - if (!poolResults) { - return res.status(404).json({ success: false, error: "team doesn't exist" }); + if (!pool) { + return res.status(404).json({ success: false, error: "Team doesn't exist" }); } // Get the teamPool @@ -47,19 +54,17 @@ module.exports = (db) => { const poolIds = teamPools.map((tp) => new ObjectId(tp.poolId)); // Fetch all pool documents - const pools = await db + const allPools = await db .collection('pool') .find({ _id: { $nin: poolIds } }) .toArray(); - const response = pools.map(({ _id, ...pool }) => ({ - id: _id, - ...pool - })); - return res.json({ success: true, - body: response + body: allPools.map(({ _id, ...pool }) => ({ + id: _id, + ...pool + })) }); } catch (error) { return res.status(500).json({ success: false, error: error.message }); diff --git a/backend/endpoints/pool/controller/removePoolFromTeam.js b/backend/endpoints/pool/controller/removePoolFromTeam.js index dcafeec..ca07909 100644 --- a/backend/endpoints/pool/controller/removePoolFromTeam.js +++ b/backend/endpoints/pool/controller/removePoolFromTeam.js @@ -14,61 +14,81 @@ module.exports = (db) => { const { teamId } = req.body || {}; const { id } = req.params || {}; + // Check id if (!id) { return res.status(400).json({ success: false, error: 'missing pool ID' }); } - if (!teamId) { - return res.status(400).json({ success: false, error: 'missing team ID' }); + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The pool ID provided is not a string' }); } const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { - return res.status(400).json({ success: false, error: 'The pool id provided is empty' }); + return res.status(400).json({ success: false, error: 'The pool ID provided is empty' }); + } + + if (!ObjectId.isValid(sanitizedId)) { + return res.status(400).json({ success: false, error: 'Invalid pool ID provided' }); + } + + // Check team id + if (!teamId) { + return res.status(400).json({ success: false, error: 'missing team ID' }); + } + + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The team ID provided is not a string' }); } const sanitizedTeamId = String(teamId).trim(); if (sanitizedTeamId.length === 0) { - return res.status(400).json({ success: false, error: 'The team id provided is empty' }); + return res.status(400).json({ success: false, error: 'The team ID provided is empty' }); + } + + if (!ObjectId.isValid(sanitizedTeamId)) { + return res.status(400).json({ success: false, error: 'Invalid team ID provided' }); } - const poolResults = await db - .collection('pool') - .findOne({ _id: new ObjectId(sanitizedId) }); + // Get pool + const pool = await db.collection('pool').findOne({ _id: new ObjectId(sanitizedId) }); - if (!poolResults) { + if (!pool) { return res.status(404).json({ success: false, error: 'Pool with that ID not found' }); } - const teamResults = await db - .collection('team') - .findOne({ _id: new ObjectId(sanitizedTeamId) }); + // Get team + const team = await db.collection('team').findOne({ _id: new ObjectId(sanitizedTeamId) }); - if (!teamResults) { + if (!team) { return res.status(404).json({ success: false, error: 'Team with that ID not found' }); } - const teamPoolResults = await db.collection('teampool').findOne({ + // Check if pool is assigned to team + const teamPool = await db.collection('teampool').findOne({ teamId: sanitizedTeamId, poolId: sanitizedId }); - if (!teamPoolResults) { + if (!teamPool) { return res .status(400) .json({ success: false, error: 'Pool is not assigned to this team' }); } + // Delete from database await db.collection('teampool').deleteOne({ teamId: sanitizedTeamId, poolId: sanitizedId }); - return res.status(200).json({ - success: true - }); + return res.status(200).json({ success: true }); } catch (error) { return res.status(500).json({ success: false, error: error.message }); } diff --git a/backend/endpoints/report/controller/addReport.js b/backend/endpoints/report/controller/addReport.js index 3f9e000..59712ce 100644 --- a/backend/endpoints/report/controller/addReport.js +++ b/backend/endpoints/report/controller/addReport.js @@ -22,14 +22,14 @@ module.exports = (db) => { } = req.body || {}; // Check cluster id + if (!clusterId) { + return res.status(400).json({ success: false, error: 'Missing cluster ID' }); + } + if (typeof clusterId !== 'string') { return res .status(400) - .json({ success: false, error: 'The cluster id provided is not a string' }); - } - - if (!clusterId) { - return res.status(400).json({ success: false, error: 'Missing cluster id' }); + .json({ success: false, error: 'The cluster ID provided is not a string' }); } const sanitizedClusterId = String(clusterId).trim(); @@ -37,7 +37,7 @@ module.exports = (db) => { if (sanitizedClusterId.length === 0) { return res .status(400) - .json({ success: false, error: 'The person id provided is empty' }); + .json({ success: false, error: 'The person ID provided is empty' }); } if (!ObjectId.isValid(sanitizedClusterId)) { @@ -55,14 +55,14 @@ module.exports = (db) => { } // Check person id + if (!personId) { + return res.status(400).json({ success: false, error: 'Missing persons ID' }); + } + if (typeof personId !== 'string') { return res .status(400) - .json({ success: false, error: 'The persons id provided is not a string' }); - } - - if (!personId) { - return res.status(400).json({ success: false, error: 'Missing persons id' }); + .json({ success: false, error: 'The persons ID provided is not a string' }); } const sanitizedPersonId = String(personId).trim(); @@ -70,11 +70,11 @@ module.exports = (db) => { if (sanitizedPersonId.length === 0) { return res .status(400) - .json({ success: false, error: 'The person id provided is empty' }); + .json({ success: false, error: 'The person ID provided is empty' }); } if (!ObjectId.isValid(sanitizedPersonId)) { - return res.status(400).json({ success: false, error: 'Invalid person id provided' }); + return res.status(400).json({ success: false, error: 'Invalid person ID provided' }); } const personExists = await db.collection('person').findOne({ @@ -88,27 +88,27 @@ module.exports = (db) => { } // Check start time + if (!startTime) { + return res.status(400).json({ success: false, error: 'Missing start time' }); + } + if (typeof startTime !== 'number') { return res .status(400) .json({ success: false, error: 'The start time provided is not a number' }); } - if (!startTime) { - return res.status(400).json({ success: false, error: 'Missing start time' }); + // Check end time + if (!endTime) { + return res.status(400).json({ success: false, error: 'Missing end time' }); } - // Check end time if (typeof endTime !== 'number') { return res .status(400) .json({ success: false, error: 'The end time provided is not a number' }); } - if (!endTime) { - return res.status(400).json({ success: false, error: 'Missing end time' }); - } - // Check results if (!results) { return res.status(400).json({ success: false, error: 'Missing results' }); diff --git a/backend/endpoints/report/controller/getDailyOverviewReport.js b/backend/endpoints/report/controller/getDailyOverviewReport.js index b1805a3..4df793f 100644 --- a/backend/endpoints/report/controller/getDailyOverviewReport.js +++ b/backend/endpoints/report/controller/getDailyOverviewReport.js @@ -72,18 +72,16 @@ module.exports = (db) => { .toArray(); const ResultsWithTitles = await Promise.all( - results - .map(async (data) => { - const instruction = await db - .collection('instruction') - .findOne({ _id: new ObjectId(data.instructionId) }); + results.map(async (data) => { + const instruction = await db + .collection('instruction') + .findOne({ _id: new ObjectId(data.instructionId) }); - return { - title: instruction.title, - ...data - }; - }) - .filter((r) => r.note || !r.passed) + return { + title: instruction.title, + ...data + }; + }) ); return { @@ -91,7 +89,7 @@ module.exports = (db) => { person: people.find((p) => p.id === rest.personId)?.name, cluster: cluster.find((c) => c.id === rest.clusterId)?.name, ...rest, - results: ResultsWithTitles + results: ResultsWithTitles.filter((r) => r.note || !r.passed) }; }) ); diff --git a/backend/services/cron/cron.js b/backend/services/cron/cron.js index a843236..3ace21b 100644 --- a/backend/services/cron/cron.js +++ b/backend/services/cron/cron.js @@ -10,8 +10,9 @@ module.exports.startPopulateClosedDays = (db) => /** * Generates the daily overview report + * 0 11 1 * @param {import('mongodb').Db} db * @returns {import('node-cron').ScheduledTask} */ module.exports.startDailyOverviewBuilder = (db) => - cron.schedule('0 11 1 * *', () => require('../dailyReport/dailyReport')(db)); + cron.schedule('* * * * *', () => require('../dailyReport/dailyReport')(db)); diff --git a/backend/services/dailyReport/dailyReport.js b/backend/services/dailyReport/dailyReport.js index 664a7bb..a343316 100644 --- a/backend/services/dailyReport/dailyReport.js +++ b/backend/services/dailyReport/dailyReport.js @@ -10,6 +10,8 @@ module.exports = async (db) => { const startOfDay = new Date().setHours(0, 0, 0, 0); const endOfDay = new Date().setHours(23, 59, 59, 999); + console.log('hello'); + // Check to see if a report exists already and if one does exit out const reportExists = await db.collection('overviewReport').findOne({ date: { @@ -69,6 +71,7 @@ module.exports = async (db) => { clusterId: value })) ); + const missingReports = []; if (rotaDaily.length != reports.length) { rotaDaily.forEach((person) => { diff --git a/frontend/app/components/ClusterSettings.jsx b/frontend/app/components/ClusterSettings.jsx index 2274524..dd403e8 100644 --- a/frontend/app/components/ClusterSettings.jsx +++ b/frontend/app/components/ClusterSettings.jsx @@ -850,7 +850,7 @@ export default function ClusterSettingsPage() { }} className="mt-4 cursor-pointer rounded-xl border border-slate-300/20 bg-slate-100/10 px-5 py-2.5 text-sm font-semibold text-slate-200 shadow-md shadow-black/20 backdrop-blur transition duration-200 hover:-translate-y-0.5 hover:border-slate-200/40 hover:bg-slate-100/15 hover:text-white" > - Close Editor X + Close Editor X )} diff --git a/frontend/app/components/Form.jsx b/frontend/app/components/Form.jsx index 7c2d9fa..2bbefb3 100644 --- a/frontend/app/components/Form.jsx +++ b/frontend/app/components/Form.jsx @@ -719,7 +719,7 @@ export default function Form() { onClick={() => setAddMethodStepID(step.id)} className="mt-8 cursor-pointer rounded-xl border border-emerald-300/25 bg-emerald-400/10 px-5 py-2.5 text-sm font-semibold text-emerald-100 shadow-md shadow-black/20 backdrop-blur transition duration-200 hover:-translate-y-0.5 hover:border-emerald-300/45 hover:bg-emerald-400/20 hover:text-white focus:outline-none focus:ring-2 focus:ring-emerald-300/45 focus:ring-offset-2 focus:ring-offset-slate-950 active:translate-y-0" > - Add Method + + Add Method + ) : (
@@ -769,7 +769,7 @@ export default function Form() { }} className="mt-8 cursor-pointer rounded-xl border border-slate-300/20 bg-slate-100/10 px-5 py-2.5 text-sm font-semibold text-slate-200 shadow-md shadow-black/20 backdrop-blur transition duration-200 hover:-translate-y-0.5 hover:border-slate-200/40 hover:bg-slate-100/15 hover:text-white focus:outline-none focus:ring-2 focus:ring-slate-200/40 focus:ring-offset-2 focus:ring-offset-slate-950 active:translate-y-0" > - Close Editor X + Close Editor X
diff --git a/frontend/app/components/Options.jsx b/frontend/app/components/Options.jsx index 47c5475..d733730 100644 --- a/frontend/app/components/Options.jsx +++ b/frontend/app/components/Options.jsx @@ -552,7 +552,7 @@ export default function Options() {

{cluster.name} diff --git a/frontend/app/components/TeamsSettingsPage.jsx b/frontend/app/components/TeamsSettingsPage.jsx index f02061e..aa57199 100644 --- a/frontend/app/components/TeamsSettingsPage.jsx +++ b/frontend/app/components/TeamsSettingsPage.jsx @@ -118,7 +118,7 @@ export default function TeamSettingsPage() { setPools(data.body ?? []); } catch (err) { - console.error('Failed to fetch availablepools:', err); + console.error('Failed to fetch available pools:', err); setPools([]); } }, [teamId]); @@ -382,11 +382,10 @@ export default function TeamSettingsPage() { {statusMessage && (

{statusMessage}
From 1ec398c3c076230847d6a019334bdf0c1bb13af0 Mon Sep 17 00:00:00 2001 From: acegoal07 <39467245+acegoal07@users.noreply.github.com> Date: Wed, 8 Jul 2026 12:18:48 +0100 Subject: [PATCH 2/8] More tweaks --- .../controller/getDailyOverviewReport.js | 9 +- .../report/controller/getReportByCluster.js | 8 +- .../report/controller/getReportById.js | 9 +- .../controller/getTodaysReportByCluster.js | 8 +- .../endpoints/rota/controller/addClosedDay.js | 17 ++-- .../rota/controller/getRotaByPerson.js | 94 +++++++++---------- backend/services/cron/cron.js | 3 +- backend/services/dailyReport/dailyReport.js | 2 - frontend/app/components/Overview.jsx | 25 ++--- 9 files changed, 89 insertions(+), 86 deletions(-) diff --git a/backend/endpoints/report/controller/getDailyOverviewReport.js b/backend/endpoints/report/controller/getDailyOverviewReport.js index 4df793f..b09e5cb 100644 --- a/backend/endpoints/report/controller/getDailyOverviewReport.js +++ b/backend/endpoints/report/controller/getDailyOverviewReport.js @@ -13,6 +13,13 @@ module.exports = (db) => { try { const { date } = req.query || {}; + // Check date + if (typeof date !== 'number') { + return res + .status(400) + .json({ success: false, error: 'The data provided is not a number' }); + } + // Get people const people = await db .collection('person') @@ -41,7 +48,7 @@ module.exports = (db) => { const startOfDay = date ? new Date(date) : new Date(); startOfDay.setHours(0, 0, 0, 0); - const endOfDay = new Date(); + const endOfDay = new Date(startOfDay); endOfDay.setHours(23, 59, 59, 999); const overviewReport = await db.collection('overviewReport').findOne({ diff --git a/backend/endpoints/report/controller/getReportByCluster.js b/backend/endpoints/report/controller/getReportByCluster.js index a6a5852..42dab67 100644 --- a/backend/endpoints/report/controller/getReportByCluster.js +++ b/backend/endpoints/report/controller/getReportByCluster.js @@ -18,16 +18,16 @@ module.exports = (db) => { const skip = (page - 1) * limit; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing cluster id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The cluster id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing cluster id' }); - } - const sanitizedClusterId = String(id).trim(); if (sanitizedClusterId.length === 0) { diff --git a/backend/endpoints/report/controller/getReportById.js b/backend/endpoints/report/controller/getReportById.js index 3ba18cd..77f5c7d 100644 --- a/backend/endpoints/report/controller/getReportById.js +++ b/backend/endpoints/report/controller/getReportById.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id } = req.params || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing the report id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The report id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing the report id' }); - } - const sanitisedId = String(id).trim(); if (sanitisedId.length === 0) { @@ -36,6 +36,7 @@ module.exports = (db) => { return res.status(400).json({ success: false, error: 'Invalid report id' }); } + // Get report const report = await db.collection('report').findOne({ _id: new ObjectId(sanitisedId) }); diff --git a/backend/endpoints/report/controller/getTodaysReportByCluster.js b/backend/endpoints/report/controller/getTodaysReportByCluster.js index e85c59d..d1fee35 100644 --- a/backend/endpoints/report/controller/getTodaysReportByCluster.js +++ b/backend/endpoints/report/controller/getTodaysReportByCluster.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id } = req.params || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing cluster id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The cluster id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing cluster id' }); - } - const sanitisedId = String(id).trim(); if (sanitisedId.length === 0) { diff --git a/backend/endpoints/rota/controller/addClosedDay.js b/backend/endpoints/rota/controller/addClosedDay.js index 4d0595c..ee1dc6e 100644 --- a/backend/endpoints/rota/controller/addClosedDay.js +++ b/backend/endpoints/rota/controller/addClosedDay.js @@ -12,16 +12,17 @@ module.exports = (db) => { const { day } = req.body || {}; // Check day - if (typeof id !== 'string') { + if (!day) { + return res.status(400).json({ success: false, error: 'Missing day' }); + } + + if (typeof day !== 'string') { return res .status(400) .json({ success: false, error: 'The day provided is not a string' }); } - if (!day) { - return res.status(400).json({ success: false, error: 'Missing day' }); - } - + // Get date const date = new Date(day); if (isNaN(date.getTime())) { @@ -30,8 +31,8 @@ module.exports = (db) => { date.setHours(0, 0, 0, 0); - const collection = db.collection('closedDay'); - const existing = await collection.findOne({ day: date }); + // Check if the day is in the database already + const existing = await db.collection('closedDay').findOne({ day: date }); if (existing) { return res @@ -39,7 +40,7 @@ module.exports = (db) => { .json({ success: false, error: 'Office already marked closed for this day' }); } - await collection.insertOne({ day: date }); + await db.collection('closedDay').insertOne({ day: date }); return res.status(201).json({ success: true, body: { day } }); } catch (error) { diff --git a/backend/endpoints/rota/controller/getRotaByPerson.js b/backend/endpoints/rota/controller/getRotaByPerson.js index 989eb9c..6599640 100644 --- a/backend/endpoints/rota/controller/getRotaByPerson.js +++ b/backend/endpoints/rota/controller/getRotaByPerson.js @@ -14,77 +14,73 @@ module.exports = (db) => { try { const { id } = req.params || {}; + // Check id if (!id) { - return res.status(400).json({ - success: false, - error: 'Missing person id' - }); + return res.status(400).json({ success: false, error: 'Missing person ID' }); } - if (!ObjectId.isValid(id)) { - return res.status(400).json({ - success: false, - error: 'Invalid person id provided' - }); + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The person ID provided is not a string' }); } - // 1. Fetch person + const sanitisedId = String(id).trim(); + + if (sanitisedId.length === 0) { + return res + .status(400) + .json({ success: false, error: 'The report id provided is empty' }); + } + + if (!ObjectId.isValid(sanitisedId)) { + return res.status(400).json({ success: false, error: 'Invalid report id' }); + } + + // Get person const person = await db.collection('person').findOne({ - _id: new ObjectId(id) + _id: new ObjectId(sanitisedId) }); if (!person) { - return res.status(404).json({ - success: false, - error: 'Person not found' - }); + return res.status(404).json({ success: false, error: 'Person not found' }); } if (!person.teamId) { - return res.status(404).json({ - success: false, - error: 'Person is not assigned to a team' - }); + return res.status(404).json({ success: false, error: 'Person is not assigned to a team' }); } - // 2. Get today's schedule + // Get today's schedule const today = new Date(); const scheduleForToday = await getDaily(db, today); - const assignedClusterIds = scheduleForToday[id] || []; - - // 3. Fetch cluster details in batch (better than per-loop lookup) - const clusters = assignedClusterIds.length - ? await db - .collection('cluster') - .find({ - _id: { $in: assignedClusterIds.map((c) => new ObjectId(c)) } - }) - .toArray() - : []; - - const clusterMap = Object.fromEntries(clusters.map((c) => [c._id.toString(), c.name])); - - // 4. Build response (same structure as weekly endpoint) - const result = { - [person.name]: { - id: person._id.toString(), - clusters: assignedClusterIds.map((id) => ({ - id, - name: clusterMap[id] ?? id - })) - } - }; + // Fetch cluster details + const assignedClusterIds = scheduleForToday[sanitisedId] || []; + const clusters = Object.fromEntries( + assignedClusterIds.length + ? await db + .collection('cluster') + .find({ + _id: { $in: assignedClusterIds.map((c) => new ObjectId(c)) } + }) + .toArray() + : [] + ).map((c) => [c._id.toString(), c.name]); return res.status(200).json({ success: true, - body: result + body: { + [person.name]: { + id: person._id.toString(), + clusters: assignedClusterIds.map((id) => ({ + id, + name: clusters[id] ?? id + })) + } + } }); } catch (error) { - return res.status(500).json({ - success: false, - error: error.message - }); + return res.status(500).json({ success: false, error: error.message }); } }; }; diff --git a/backend/services/cron/cron.js b/backend/services/cron/cron.js index 3ace21b..a843236 100644 --- a/backend/services/cron/cron.js +++ b/backend/services/cron/cron.js @@ -10,9 +10,8 @@ module.exports.startPopulateClosedDays = (db) => /** * Generates the daily overview report - * 0 11 1 * @param {import('mongodb').Db} db * @returns {import('node-cron').ScheduledTask} */ module.exports.startDailyOverviewBuilder = (db) => - cron.schedule('* * * * *', () => require('../dailyReport/dailyReport')(db)); + cron.schedule('0 11 1 * *', () => require('../dailyReport/dailyReport')(db)); diff --git a/backend/services/dailyReport/dailyReport.js b/backend/services/dailyReport/dailyReport.js index a343316..3b8257c 100644 --- a/backend/services/dailyReport/dailyReport.js +++ b/backend/services/dailyReport/dailyReport.js @@ -10,8 +10,6 @@ module.exports = async (db) => { const startOfDay = new Date().setHours(0, 0, 0, 0); const endOfDay = new Date().setHours(23, 59, 59, 999); - console.log('hello'); - // Check to see if a report exists already and if one does exit out const reportExists = await db.collection('overviewReport').findOne({ date: { diff --git a/frontend/app/components/Overview.jsx b/frontend/app/components/Overview.jsx index f2a5ad0..5bef612 100644 --- a/frontend/app/components/Overview.jsx +++ b/frontend/app/components/Overview.jsx @@ -35,9 +35,9 @@ export default function Overview() { try { const res = await fetch( `${process.env.NEXT_PUBLIC_API_URL}/report/overview` + - `?${new URLSearchParams({ - date: date - }).toString()}` + `?${new URLSearchParams({ + date: date + }).toString()}` ); const data = await res.json(); setReport(data?.body ?? {}); @@ -52,6 +52,10 @@ export default function Overview() { loadReportFromDate(); }, [date]); + useEffect(() => { + console.log(report) + }, [report]); + // Calculate duration function calculateDuration(start, end) { const diffMs = end.getTime() - start.getTime(); @@ -117,9 +121,8 @@ export default function Overview() { type="date" value={date} onChange={(e) => setDate(e.target.value)} - className={`block w-full min-w-0 max-w-[15rem] rounded-lg border border-slate-600 bg-slate-800/80 px-2.5 py-2 text-xs [color-scheme:dark] sm:max-w-full sm:rounded-xl sm:px-4 sm:py-3 sm:text-base ${ - date ? 'text-white' : 'text-transparent sm:text-white' - }`} + className={`block w-full min-w-0 max-w-[15rem] rounded-lg border border-slate-600 bg-slate-800/80 px-2.5 py-2 text-xs [color-scheme:dark] sm:max-w-full sm:rounded-xl sm:px-4 sm:py-3 sm:text-base ${date ? 'text-white' : 'text-transparent sm:text-white' + }`} /> {!date && ( @@ -156,11 +159,10 @@ export default function Overview() { {/* Status */}
{element.passed ? 'Passed' : 'Failed'} @@ -209,11 +211,10 @@ export default function Overview() { {result.passed ? 'Passed' : 'Failed'} From 707ebd0aededd07eb85a692b72446e55a1f75ef0 Mon Sep 17 00:00:00 2001 From: acegoal07 <39467245+acegoal07@users.noreply.github.com> Date: Wed, 8 Jul 2026 13:39:33 +0100 Subject: [PATCH 3/8] Starts work on new variable naming --- .../controller/getRandomBonusChallenge.js | 2 +- .../checkFocus/controller/getRandomFocus.js | 3 ++ backend/endpoints/checkFocus/route.js | 5 +- backend/endpoints/hpc/controller/addHpc.js | 14 ++--- .../endpoints/hpc/controller/addHpcToPool.js | 52 +++++++++---------- backend/endpoints/hpc/controller/deleteHpc.js | 28 +++++----- .../endpoints/hpc/controller/getHpcById.js | 26 +++++----- .../endpoints/hpc/controller/getHpcByName.js | 12 ++--- .../endpoints/hpc/controller/getHpcByPool.js | 28 +++++----- .../hpc/controller/getHpcNotInPool.js | 16 +++--- .../hpc/controller/removeHpcFromPool.js | 34 ++++++------ .../endpoints/rota/controller/addClosedDay.js | 12 ++++- .../rota/controller/getRotaByPerson.js | 17 +++--- backend/endpoints/team/controller/addTeam.js | 8 +-- .../endpoints/team/controller/deleteTeam.js | 20 ++++--- .../endpoints/team/controller/getTeamById.js | 14 ++--- .../team/controller/getTeamByName.js | 8 +-- .../team/controller/getTeamByPool.js | 30 ++++++----- .../team/controller/updateTeamSettings.js | 8 +-- 19 files changed, 182 insertions(+), 155 deletions(-) diff --git a/backend/endpoints/bonusChallenge/controller/getRandomBonusChallenge.js b/backend/endpoints/bonusChallenge/controller/getRandomBonusChallenge.js index bbcf0e5..df5544d 100644 --- a/backend/endpoints/bonusChallenge/controller/getRandomBonusChallenge.js +++ b/backend/endpoints/bonusChallenge/controller/getRandomBonusChallenge.js @@ -37,7 +37,7 @@ module.exports = (db) => { })) ); - // Check if a bonus question got returned from the question + // Check if a bonus question was chosen if (!response) { return res .status(404) diff --git a/backend/endpoints/checkFocus/controller/getRandomFocus.js b/backend/endpoints/checkFocus/controller/getRandomFocus.js index c5a4857..60f17ed 100644 --- a/backend/endpoints/checkFocus/controller/getRandomFocus.js +++ b/backend/endpoints/checkFocus/controller/getRandomFocus.js @@ -9,10 +9,12 @@ module.exports = (db) => { */ return async (req, res) => { try { + // Check to see if the user gets a focus if (Math.random() >= 0.2) { return res.status(200).json({ success: true, body: null }); } + // Get a random focus from the database const checkFocus = await db .collection('checkFocus') .aggregate([ @@ -35,6 +37,7 @@ module.exports = (db) => { })) ); + // Check if a focus was chosen if (!checkFocus[0]) { return res.status(404).json({ success: false, error: 'No active focuses found' }); } diff --git a/backend/endpoints/checkFocus/route.js b/backend/endpoints/checkFocus/route.js index f319c43..0c7ea87 100644 --- a/backend/endpoints/checkFocus/route.js +++ b/backend/endpoints/checkFocus/route.js @@ -1,5 +1,8 @@ +/** + * @param {import('mongodb').Db} db + */ module.exports = (db) => require('express') .Router() - + // GET .get('/check-focus/random', require('./controller/getRandomFocus')(db)); diff --git a/backend/endpoints/hpc/controller/addHpc.js b/backend/endpoints/hpc/controller/addHpc.js index e572896..7a53325 100644 --- a/backend/endpoints/hpc/controller/addHpc.js +++ b/backend/endpoints/hpc/controller/addHpc.js @@ -11,22 +11,22 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { name } = req.body || {}; + const { name: rawName } = req.body || {}; // Check name - if (!name) { + if (rawName === undefined || rawName === null) { return res.status(400).json({ success: false, error: 'Missing cluster name' }); } - if (typeof name !== 'string') { + if (typeof rawName !== 'string') { return res .status(400) .json({ success: false, error: 'The cluster name provided is not a string' }); } - const sanitizedName = String(name).trim(); + const clusterName = rawName.trim(); - if (sanitizedName.length == 0) { + if (!clusterName) { return res .status(400) .json({ success: false, error: 'The cluster name provided is empty' }); @@ -35,7 +35,7 @@ module.exports = (db) => { // Check if hpc already exists const existing = await db.collection('cluster').findOne({ name: { - $regex: `^${sanitizedName}$`, + $regex: `^${clusterName}$`, $options: 'i' } }); @@ -48,7 +48,7 @@ module.exports = (db) => { const clusterId = await db .collection('cluster') .insertOne({ - name: sanitizedName + name: clusterName }) .then((res) => res.insertedId.toString()); diff --git a/backend/endpoints/hpc/controller/addHpcToPool.js b/backend/endpoints/hpc/controller/addHpcToPool.js index 572e615..7983d84 100644 --- a/backend/endpoints/hpc/controller/addHpcToPool.js +++ b/backend/endpoints/hpc/controller/addHpcToPool.js @@ -11,63 +11,63 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id } = req.params || {}; - const { poolId } = req.body || {}; + const { id: rawClusterId } = req.params || {}; + const { poolId: rawPoolId } = req.body || {}; - // Check id - if (typeof id !== 'string') { + // Check cluster id + if (rawClusterId === undefined || rawClusterId === null) { + return res.status(400).json({ success: false, error: 'Missing cluster ID' }); + } + + if (typeof rawClusterId !== 'string') { return res .status(400) .json({ success: false, error: 'The cluster ID provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing cluster ID' }); - } - - const sanitizedId = String(id).trim(); + const clusterId = rawClusterId.trim(); - if (sanitizedId.length === 0) { + if (!clusterId) { return res .status(400) .json({ success: false, error: 'The cluster ID provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { + if (!ObjectId.isValid(clusterId)) { return res.status(400).json({ success: false, error: 'Invalid cluster ID provided' }); } // Check pool id - if (typeof poolId !== 'string') { + if (rawPoolId === undefined || rawPoolId === null) { + return res.status(400).json({ success: false, error: 'Missing pool ID' }); + } + + if (typeof rawPoolId !== 'string') { return res .status(400) .json({ success: false, error: 'The pool ID provided is not a string' }); } - if (!poolId) { - return res.status(400).json({ success: false, error: 'Missing pool ID' }); - } - - const sanitizedPoolId = String(poolId).trim(); + const poolId = rawPoolId.trim(); - if (sanitizedPoolId.length === 0) { + if (!poolId) { return res.status(400).json({ success: false, error: 'The pool ID provided is empty' }); } - if (!ObjectId.isValid(sanitizedPoolId)) { + if (!ObjectId.isValid(poolId)) { return res.status(400).json({ success: false, error: 'Invalid pool ID provided' }); } // Get the cluster const cluster = await db.collection('cluster').findOne({ - _id: new ObjectId(sanitizedId) + _id: new ObjectId(clusterId) }); if (!cluster) { return res.status(404).json({ success: false, error: "Cluster doesn't exist" }); } - if (cluster.poolId === sanitizedPoolId) { + if (cluster.poolId === clusterId) { return res .status(400) .json({ success: false, error: 'Cluster already assigned to pool' }); @@ -75,7 +75,7 @@ module.exports = (db) => { // Get pool const pool = await db.collection('pool').findOne({ - _id: new ObjectId(sanitizedPoolId) + _id: new ObjectId(poolId) }); if (!pool) { @@ -83,10 +83,10 @@ module.exports = (db) => { } db.collection('cluster').updateOne( - { _id: new ObjectId(sanitizedId) }, + { _id: new ObjectId(clusterId) }, { $set: { - poolId: sanitizedPoolId + poolId: poolId } } ); @@ -94,9 +94,9 @@ module.exports = (db) => { return res.status(200).json({ success: true, body: { - id: sanitizedId, + id: clusterId, name: cluster.name, - poolId: sanitizedPoolId + poolId: poolId } }); } catch (error) { diff --git a/backend/endpoints/hpc/controller/deleteHpc.js b/backend/endpoints/hpc/controller/deleteHpc.js index e285199..fcce06d 100644 --- a/backend/endpoints/hpc/controller/deleteHpc.js +++ b/backend/endpoints/hpc/controller/deleteHpc.js @@ -11,34 +11,34 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id } = req.params; + const { id: rawClusterId } = req.params; - // Check id - if (!id) { - return res.status(400).json({ success: false, error: 'Missing cluster id' }); + // Check cluster id + if (rawClusterId === undefined || rawClusterId === null) { + return res.status(400).json({ success: false, error: 'Missing cluster ID' }); } - if (typeof id !== 'string') { + if (typeof rawClusterId !== 'string') { return res .status(400) - .json({ success: false, error: 'The cluster id provided is not a string' }); + .json({ success: false, error: 'The cluster ID provided is not a string' }); } - const sanitizedId = String(id).trim(); + const clusterId = rawClusterId.trim(); - if (sanitizedId.length === 0) { + if (!clusterId) { return res .status(400) - .json({ success: false, error: "The cluster id you've provided is empty" }); + .json({ success: false, error: 'The cluster ID provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid cluster id provided' }); + if (!ObjectId.isValid(clusterId)) { + return res.status(400).json({ success: false, error: 'Invalid cluster ID provided' }); } // Get cluster const cluster = await db.collection('cluster').findOneAndDelete({ - _id: new ObjectId(sanitizedId) + _id: new ObjectId(clusterId) }); if (!cluster) { @@ -52,7 +52,7 @@ module.exports = (db) => { const reports = await db .collection('report') .find({ - clusterId: sanitizedId + clusterId: clusterId }) .toArray() .then((res) => @@ -80,7 +80,7 @@ module.exports = (db) => { const instructions = await db .collection('instruction') .find({ - clusterId: new ObjectId(sanitizedId) + clusterId: new ObjectId(clusterId) }) .toArray() .then((res) => diff --git a/backend/endpoints/hpc/controller/getHpcById.js b/backend/endpoints/hpc/controller/getHpcById.js index d3d9f33..218970b 100644 --- a/backend/endpoints/hpc/controller/getHpcById.js +++ b/backend/endpoints/hpc/controller/getHpcById.js @@ -11,41 +11,41 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id } = req.params || {}; + const { id: rawClusterId } = req.params || {}; - // Check id - if (!id) { - return res.status(400).json({ success: false, error: 'Missing cluster id' }); + // Check cluster id + if (rawClusterId === undefined || rawClusterId === null) { + return res.status(400).json({ success: false, error: 'Missing cluster ID' }); } - if (typeof id !== 'string') { + if (typeof rawClusterId !== 'string') { return res .status(400) - .json({ success: false, error: 'The cluster id provided is not a string' }); + .json({ success: false, error: 'The cluster ID provided is not a string' }); } - const sanitizedId = String(id).trim(); + const clusterId = rawClusterId.trim(); - if (sanitizedId.length === 0) { + if (!clusterId) { return res .status(400) - .json({ success: false, error: 'The cluster id provided is empty' }); + .json({ success: false, error: 'The cluster ID provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid cluster id provided' }); + if (!ObjectId.isValid(clusterId)) { + return res.status(400).json({ success: false, error: 'Invalid cluster ID provided' }); } // Get the cluster const response = await db.collection('cluster').findOne({ - _id: new ObjectId(sanitizedId) + _id: new ObjectId(clusterId) }); if (!response) { return res.status(404).json({ success: false, error: "Cluster doesn't exist" }); } - response.id = sanitizedId; + response.id = clusterId; delete response._id; return res.status(200).json({ diff --git a/backend/endpoints/hpc/controller/getHpcByName.js b/backend/endpoints/hpc/controller/getHpcByName.js index 6afe8e3..6ac78bb 100644 --- a/backend/endpoints/hpc/controller/getHpcByName.js +++ b/backend/endpoints/hpc/controller/getHpcByName.js @@ -9,29 +9,29 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { name } = req.params || {}; + const { name: rawName } = req.params || {}; // Check name - if (!name) { + if (rawName === undefined || rawName === null) { return res.status(400).json({ success: false, error: 'Missing cluster name' }); } - if (typeof name !== 'string') { + if (typeof rawName !== 'string') { return res .status(400) .json({ success: false, error: 'The cluster name provided is not a string' }); } - const sanitizedName = String(name).trim(); + const name = rawName.trim(); - if (sanitizedName.length == 0) { + if (!name) { return res.status(400).json({ success: false, error: 'The name provided is empty' }); } // Get the cluster const response = await db.collection('cluster').findOne({ name: { - $regex: `^${sanitizedName}$`, + $regex: `^${name}$`, $options: 'i' } }); diff --git a/backend/endpoints/hpc/controller/getHpcByPool.js b/backend/endpoints/hpc/controller/getHpcByPool.js index d8ead17..2dadc54 100644 --- a/backend/endpoints/hpc/controller/getHpcByPool.js +++ b/backend/endpoints/hpc/controller/getHpcByPool.js @@ -11,34 +11,34 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id } = req.params || {}; + const { id: rawPoolId } = req.params || {}; - // Check id - if (!id) { - return res.status(400).json({ success: false, error: 'Missing pool id' }); + // Check pool id + if (rawPoolId === undefined || rawPoolId === null) { + return res.status(400).json({ success: false, error: 'Missing pool ID' }); } - if (typeof id !== 'string') { + if (typeof rawPoolId !== 'string') { return res .status(400) - .json({ success: false, error: 'The pool id provided is not a string' }); + .json({ success: false, error: 'The pool ID provided is not a string' }); } - const sanitizedId = String(id).trim(); + const poolId = rawPoolId.trim(); - if (sanitizedId.length === 0) { - return res.status(400).json({ success: false, error: 'The pool id provided is empty' }); + if (poolId.length === 0) { + return res.status(400).json({ success: false, error: 'The pool ID provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid pool id provided' }); + if (!ObjectId.isValid(poolId)) { + return res.status(400).json({ success: false, error: 'Invalid pool ID provided' }); } // Get the cluster - const respone = await db + const response = await db .collection('cluster') .find({ - poolId: sanitizedId + poolId: poolId }) .toArray() .then((res) => @@ -48,7 +48,7 @@ module.exports = (db) => { })) ); - return res.status(200).json({ success: true, body: respone }); + return res.status(200).json({ success: true, body: response }); } catch (error) { return res.status(500).json({ success: false, error: error.message }); } diff --git a/backend/endpoints/hpc/controller/getHpcNotInPool.js b/backend/endpoints/hpc/controller/getHpcNotInPool.js index 9efeda3..e36a5cf 100644 --- a/backend/endpoints/hpc/controller/getHpcNotInPool.js +++ b/backend/endpoints/hpc/controller/getHpcNotInPool.js @@ -11,26 +11,26 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id } = req.params || {}; + const { id: rawPoolId } = req.params || {}; - // Check id - if (!id) { + // Check pool id + if (rawPoolId === undefined || rawPoolId === null) { return res.status(400).json({ success: false, error: 'Missing pool id' }); } - if (typeof id !== 'string') { + if (typeof rawPoolId !== 'string') { return res .status(400) .json({ success: false, error: 'The pool id provided is not a string' }); } - const sanitizedId = String(id).trim(); + const poolId = String(rawPoolId).trim(); - if (sanitizedId.length === 0) { + if (poolId.length === 0) { return res.status(400).json({ success: false, error: 'The pool id provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { + if (!ObjectId.isValid(poolId)) { return res.status(400).json({ success: false, error: 'Invalid pool id provided' }); } @@ -38,7 +38,7 @@ module.exports = (db) => { const response = await db .collection('cluster') .find({ - poolId: { $ne: sanitizedId } + poolId: { $ne: poolId } }) .toArray() .then((res) => diff --git a/backend/endpoints/hpc/controller/removeHpcFromPool.js b/backend/endpoints/hpc/controller/removeHpcFromPool.js index 89b8773..e381c04 100644 --- a/backend/endpoints/hpc/controller/removeHpcFromPool.js +++ b/backend/endpoints/hpc/controller/removeHpcFromPool.js @@ -11,56 +11,56 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id } = req.params || {}; - const { poolId } = req.body || {}; + const { id: rawClusterId } = req.params || {}; + const { poolId: rawPoolId } = req.body || {}; // Check id - if (!id) { + if (rawClusterId === undefined || rawClusterId === null) { return res.status(400).json({ success: false, error: 'Missing cluster id' }); } - if (typeof id !== 'string') { + if (typeof rawClusterId !== 'string') { return res .status(400) .json({ success: false, error: 'The cluster id provided is not a string' }); } - const sanitizedId = String(id).trim(); + const clusterId = rawClusterId.trim(); - if (sanitizedId.length === 0) { + if (!clusterId) { return res .status(400) .json({ success: false, error: 'The cluster id provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { + if (!ObjectId.isValid(clusterId)) { return res.status(400).json({ success: false, error: 'Invalid cluster id provided' }); } // Check pool id - if (!poolId) { + if (rawPoolId === undefined || rawPoolId === null) { return res.status(400).json({ success: false, error: 'Missing pool id' }); } - if (typeof poolId !== 'string') { + if (typeof rawPoolId !== 'string') { return res .status(400) .json({ success: false, error: 'The pool id provided is not a string' }); } - const sanitizedPoolId = String(poolId).trim(); + const poolId = String(rawPoolId).trim(); - if (sanitizedPoolId.length === 0) { + if (!poolId) { return res.status(400).json({ success: false, error: 'The pool id provided is empty' }); } - if (!ObjectId.isValid(sanitizedPoolId)) { + if (!ObjectId.isValid(poolId)) { return res.status(400).json({ success: false, error: 'Invalid pool id provided' }); } // Get the cluster const cluster = await db.collection('cluster').findOne({ - _id: new ObjectId(sanitizedId) + _id: new ObjectId(clusterId) }); if (!cluster) { @@ -69,20 +69,20 @@ module.exports = (db) => { // Get the pool const pool = await db.collection('pool').findOne({ - _id: new ObjectId(sanitizedPoolId) + _id: new ObjectId(poolId) }); if (!pool) { return res.status(404).json({ success: false, error: "Pool doesn't exist" }); } - if (!cluster.poolId === sanitizedPoolId) { + if (!cluster.poolId === poolId) { return res.status(400).json({ success: false, error: 'Cluster not assigned to pool' }); } // Update database db.collection('cluster').updateOne( - { _id: new ObjectId(sanitizedId) }, + { _id: new ObjectId(clusterId) }, { $unset: { poolId: '' @@ -93,7 +93,7 @@ module.exports = (db) => { return res.status(200).json({ success: true, body: { - id: sanitizedId, + id: clusterId, name: cluster.name } }); diff --git a/backend/endpoints/rota/controller/addClosedDay.js b/backend/endpoints/rota/controller/addClosedDay.js index ee1dc6e..6ee65e3 100644 --- a/backend/endpoints/rota/controller/addClosedDay.js +++ b/backend/endpoints/rota/controller/addClosedDay.js @@ -22,8 +22,16 @@ module.exports = (db) => { .json({ success: false, error: 'The day provided is not a string' }); } + const sanitisedDay = String(day).trim(); + + if (sanitisedDay.length === 0) { + return res + .status(400) + .json({ success: false, error: 'The report id provided is empty' }); + } + // Get date - const date = new Date(day); + const date = new Date(sanitisedDay); if (isNaN(date.getTime())) { return res.status(400).json({ success: false, error: 'Invalid date' }); @@ -42,7 +50,7 @@ module.exports = (db) => { await db.collection('closedDay').insertOne({ day: date }); - return res.status(201).json({ success: true, body: { day } }); + return res.status(201).json({ success: true, body: { day: sanitisedDay } }); } catch (error) { return res.status(500).json({ success: false, error: error.message }); } diff --git a/backend/endpoints/rota/controller/getRotaByPerson.js b/backend/endpoints/rota/controller/getRotaByPerson.js index 6599640..e1e4361 100644 --- a/backend/endpoints/rota/controller/getRotaByPerson.js +++ b/backend/endpoints/rota/controller/getRotaByPerson.js @@ -47,7 +47,9 @@ module.exports = (db) => { } if (!person.teamId) { - return res.status(404).json({ success: false, error: 'Person is not assigned to a team' }); + return res + .status(404) + .json({ success: false, error: 'Person is not assigned to a team' }); } // Get today's schedule @@ -59,13 +61,14 @@ module.exports = (db) => { const clusters = Object.fromEntries( assignedClusterIds.length ? await db - .collection('cluster') - .find({ - _id: { $in: assignedClusterIds.map((c) => new ObjectId(c)) } - }) - .toArray() + .collection('cluster') + .find({ + _id: { $in: assignedClusterIds.map((c) => new ObjectId(c)) } + }) + .toArray() + .then((res) => res.map((c) => [c._id.toString(), c.name])) : [] - ).map((c) => [c._id.toString(), c.name]); + ); return res.status(200).json({ success: true, diff --git a/backend/endpoints/team/controller/addTeam.js b/backend/endpoints/team/controller/addTeam.js index a830540..121bf3f 100644 --- a/backend/endpoints/team/controller/addTeam.js +++ b/backend/endpoints/team/controller/addTeam.js @@ -12,16 +12,16 @@ module.exports = (db) => { const { name } = req.body || {}; // Check name + if (!name) { + return res.status(400).json({ success: false, error: "Missing team's name" }); + } + if (typeof name !== 'string') { return res .status(400) .json({ success: false, error: 'The name provided is not a string' }); } - if (!name) { - return res.status(400).json({ success: false, error: "Missing team's name" }); - } - const sanitizedName = String(name).trim(); if (sanitizedName.length == 0) { diff --git a/backend/endpoints/team/controller/deleteTeam.js b/backend/endpoints/team/controller/deleteTeam.js index d21ee26..d7a6bf2 100644 --- a/backend/endpoints/team/controller/deleteTeam.js +++ b/backend/endpoints/team/controller/deleteTeam.js @@ -15,17 +15,23 @@ module.exports = (db) => { // Check id if (!id) { - return res.status(400).json({ success: false, error: "Missing team's id" }); + return res.status(400).json({ success: false, error: 'Missing team ID' }); + } + + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The team ID provided is not a string' }); } const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { - return res.status(400).json({ success: false, error: 'The team id provided is empty' }); + return res.status(400).json({ success: false, error: 'The team ID provided is empty' }); } if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid team id provided' }); + return res.status(400).json({ success: false, error: 'Invalid team ID provided' }); } // Check if team exists @@ -38,26 +44,26 @@ module.exports = (db) => { } // Check if people are linked to the team - const hasPeople = await db + const people = await db .collection('person') .find({ teamId: sanitizedId }) .toArray(); - if (hasPeople.length > 0) { + if (people.length > 0) { return res.status(409).json({ success: false, error: 'This team has people' }); } // Check if clusters are linked to the team - const hasClusters = await db + const clusters = await db .collection('teampool') .find({ teamId: sanitizedId }) .toArray(); - if (hasClusters.length > 0) { + if (clusters.length > 0) { return res.status(409).json({ success: false, error: 'This team has pools' }); } diff --git a/backend/endpoints/team/controller/getTeamById.js b/backend/endpoints/team/controller/getTeamById.js index 7616732..484555f 100644 --- a/backend/endpoints/team/controller/getTeamById.js +++ b/backend/endpoints/team/controller/getTeamById.js @@ -14,24 +14,24 @@ module.exports = (db) => { const { id } = req.params || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing teams ID' }); + } + if (typeof id !== 'string') { return res .status(400) - .json({ success: false, error: 'The team id provided is not a string' }); - } - - if (!id) { - return res.status(400).json({ success: false, error: 'Missing teams id' }); + .json({ success: false, error: 'The team ID provided is not a string' }); } const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { - return res.status(400).json({ success: false, error: 'The team id provided is empty' }); + return res.status(400).json({ success: false, error: 'The team ID provided is empty' }); } if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid team id provided' }); + return res.status(400).json({ success: false, error: 'Invalid team ID provided' }); } // Get the team diff --git a/backend/endpoints/team/controller/getTeamByName.js b/backend/endpoints/team/controller/getTeamByName.js index 8073d59..02c92e8 100644 --- a/backend/endpoints/team/controller/getTeamByName.js +++ b/backend/endpoints/team/controller/getTeamByName.js @@ -12,16 +12,16 @@ module.exports = (db) => { const { name } = req.params || {}; // Check name + if (!name) { + return res.status(400).json({ success: false, error: 'Missing team name' }); + } + if (typeof name !== 'string') { return res .status(400) .json({ success: false, error: 'The team name provided is not a string' }); } - if (!name) { - return res.status(400).json({ success: false, error: 'Missing teams name' }); - } - const sanitizedName = String(name).trim(); if (sanitizedName.length == 0) { diff --git a/backend/endpoints/team/controller/getTeamByPool.js b/backend/endpoints/team/controller/getTeamByPool.js index e91fc7e..7e1056d 100644 --- a/backend/endpoints/team/controller/getTeamByPool.js +++ b/backend/endpoints/team/controller/getTeamByPool.js @@ -15,43 +15,47 @@ module.exports = (db) => { // Check id if (!id) { - return res.status(400).json({ success: false, error: 'Missing pool id' }); + return res.status(400).json({ success: false, error: 'Missing pool ID' }); + } + + if (typeof id !== 'string') { + return res + .status(400) + .json({ success: false, error: 'The team ID provided is not a string' }); } const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { - return res.status(400).json({ success: false, error: 'The pool id provided is empty' }); + return res.status(400).json({ success: false, error: 'The pool ID provided is empty' }); } if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'Invalid pool id provided' }); + return res.status(400).json({ success: false, error: 'Invalid pool ID provided' }); } - const poolResults = await db.collection('pool').findOne({ + const pool = await db.collection('pool').findOne({ _id: new ObjectId(sanitizedId) }); - if (!poolResults) { + if (!pool) { return res.status(404).json({ success: false, error: "Pool doesn't exist" }); } // Get the teamPool - const results = await db.collection('teampool').find({ poolId: sanitizedId }).toArray(); + const teamPool = await db.collection('teampool').find({ poolId: sanitizedId }).toArray(); - if (results.length === 0) { + if (teamPool.length === 0) { return res.status(404).json({ success: false, error: 'Pool does not have any teams' }); } - const formattedResponse = results.map((result) => ({ - poolId: sanitizedId, - teamId: result.teamId - })); - // Return the team information return res.status(200).json({ success: true, - body: formattedResponse + body: teamPool.map((result) => ({ + poolId: sanitizedId, + teamId: result.teamId + })) }); } catch (error) { return res.status(500).json({ success: false, error: error.message }); diff --git a/backend/endpoints/team/controller/updateTeamSettings.js b/backend/endpoints/team/controller/updateTeamSettings.js index f18f093..dc557fb 100644 --- a/backend/endpoints/team/controller/updateTeamSettings.js +++ b/backend/endpoints/team/controller/updateTeamSettings.js @@ -14,16 +14,16 @@ module.exports = (db) => { const { id, ...rest } = req.body || {}; // Check id + if (!id) { + return res.status(400).json({ success: false, error: 'Missing team id' }); + } + if (typeof id !== 'string') { return res .status(400) .json({ success: false, error: 'The team id provided is not a string' }); } - if (!id) { - return res.status(400).json({ success: false, error: 'Missing team id' }); - } - const sanitizedId = String(id).trim(); if (sanitizedId.length === 0) { From a17550e86df3b4f3a78a5ae7167ebeda643e99f4 Mon Sep 17 00:00:00 2001 From: acegoal07 <39467245+acegoal07@users.noreply.github.com> Date: Wed, 8 Jul 2026 13:39:49 +0100 Subject: [PATCH 4/8] Update removeHpcFromPool.js --- backend/endpoints/hpc/controller/removeHpcFromPool.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/endpoints/hpc/controller/removeHpcFromPool.js b/backend/endpoints/hpc/controller/removeHpcFromPool.js index e381c04..f399609 100644 --- a/backend/endpoints/hpc/controller/removeHpcFromPool.js +++ b/backend/endpoints/hpc/controller/removeHpcFromPool.js @@ -48,7 +48,7 @@ module.exports = (db) => { .json({ success: false, error: 'The pool id provided is not a string' }); } - const poolId = String(rawPoolId).trim(); + const poolId = rawPoolId.trim(); if (!poolId) { return res.status(400).json({ success: false, error: 'The pool id provided is empty' }); From 8552c84b4acfe7bc742d3caf9a446bb73c74d9a1 Mon Sep 17 00:00:00 2001 From: acegoal07 <39467245+acegoal07@users.noreply.github.com> Date: Wed, 8 Jul 2026 14:00:36 +0100 Subject: [PATCH 5/8] cleans more --- .../instruction/controller/addInstruction.js | 77 ++++++++++--------- .../controller/deleteInstruction.js | 20 +++-- .../controller/getAllInstructionsData.js | 19 ++--- .../controller/getAllInstructionsOnly.js | 18 ++--- .../controller/getInstructionsAllById.js | 42 +++++----- .../controller/getInstructionsOnlyById.js | 16 ++-- .../controller/updateInstruction.js | 26 +++---- 7 files changed, 107 insertions(+), 111 deletions(-) diff --git a/backend/endpoints/instruction/controller/addInstruction.js b/backend/endpoints/instruction/controller/addInstruction.js index 475799a..5f49d4d 100644 --- a/backend/endpoints/instruction/controller/addInstruction.js +++ b/backend/endpoints/instruction/controller/addInstruction.js @@ -11,123 +11,130 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { title, expectedTime, description, clusterId, good, bad } = req.body || {}; + const { + title: rawTitle, + expectedTime: rawExpectedTime, + description: rawDescription, + clusterId: rawClusterId, + good: rawGood, + bad: rawBad + } = req.body || {}; // Check title - if (!title) { + if (rawTitle === undefined || rawTitle === null) { return res.status(400).json({ success: false, error: 'Missing instruction title' }); } - if (typeof title !== 'string') { + if (typeof rawTitle !== 'string') { return res .status(400) .json({ success: false, error: 'The title provided is not a string' }); } - const sanitizedTitle = String(title).trim(); + const title = rawTitle.trim(); - if (sanitizedTitle.length == 0) { + if (!title) { return res.status(400).json({ success: false, error: 'The title provided is empty' }); } // Check expected time - if (!expectedTime) { + if (rawExpectedTime === undefined || rawExpectedTime === null) { return res.status(400).json({ success: false, error: 'Missing expected time' }); } - if (typeof expectedTime !== 'string') { + if (typeof rawExpectedTime !== 'string') { return res .status(400) .json({ success: false, error: 'The expected time provided is not a string' }); } - const sanitizedExpectedTime = String(expectedTime).trim(); + const expectedTime = rawExpectedTime.trim(); - if (sanitizedExpectedTime.length == 0) { + if (!expectedTime) { return res .status(400) .json({ success: false, error: 'The expected time provided is empty' }); } // Check description - if (!description) { + if (rawDescription === undefined || rawDescription === null) { return res.status(400).json({ success: false, error: 'Missing description' }); } - if (typeof description !== 'string') { + if (typeof rawDescription !== 'string') { return res .status(400) .json({ success: false, error: 'The description provided is not a string' }); } - const sanitizedDescription = String(description).trim(); + const description = rawDescription.trim(); - if (sanitizedDescription.length == 0) { + if (!description) { return res .status(400) .json({ success: false, error: 'The descriptions provided is empty' }); } // Check cluster id - if (!clusterId) { + if (rawClusterId === undefined || rawClusterId === null) { return res.status(400).json({ success: false, error: 'Missing cluster id' }); } - if (typeof clusterId !== 'string') { + if (typeof rawClusterId !== 'string') { return res .status(400) .json({ success: false, error: 'The cluster id provided is not a string' }); } - const sanitizedClusterId = String(clusterId).trim(); + const clusterId = rawClusterId.trim(); - if (sanitizedClusterId.length == 0) { + if (!clusterId) { return res .status(400) .json({ success: false, error: 'The cluster id provided is empty' }); } - if (!ObjectId.isValid(sanitizedClusterId)) { + if (!ObjectId.isValid(clusterId)) { return res.status(400).json({ success: false, error: 'Invalid cluster id provided' }); } // Check good - if (!good) { + if (rawGood === undefined || rawGood === null) { return res.status(400).json({ success: false, error: 'Missing instruction title' }); } - if (typeof good !== 'string') { + if (typeof rawGood !== 'string') { return res .status(400) .json({ success: false, error: 'The good provided is not a string' }); } - const sanitizedGood = String(good).trim(); + const good = rawGood.trim(); - if (sanitizedGood.length == 0) { + if (!good) { return res.status(400).json({ success: false, error: 'The good provided is empty' }); } // Check bad - if (!bad) { + if (rawBad === undefined || rawBad === null) { return res.status(400).json({ success: false, error: 'Missing instruction title' }); } - if (typeof bad !== 'string') { + if (typeof rawBad !== 'string') { return res .status(400) .json({ success: false, error: 'The bad provided is not a string' }); } - const sanitizedBad = String(bad).trim(); + const bad = rawBad.trim(); - if (sanitizedBad.length == 0) { + if (bad.length == 0) { return res.status(400).json({ success: false, error: 'The bad provided is empty' }); } // Get cluster const cluster = await db.collection('cluster').findOne({ - _id: new ObjectId(sanitizedClusterId) + _id: new ObjectId(clusterId) }); if (!cluster) { @@ -138,16 +145,14 @@ module.exports = (db) => { // Add to database await db.collection('instruction').insertOne({ - title: sanitizedTitle, - expectedTime: sanitizedExpectedTime, - description: sanitizedDescription, - clusterId: sanitizedClusterId, - good: sanitizedGood, - bad: sanitizedBad, + title: title, + expectedTime: expectedTime, + description: description, + clusterId: clusterId, + good: good, + bad: bad, position: - (await db - .collection('instruction') - .countDocuments({ clusterId: sanitizedClusterId })) + 1 + (await db.collection('instruction').countDocuments({ clusterId: clusterId })) + 1 }); return res.status(200).json({ success: true }); diff --git a/backend/endpoints/instruction/controller/deleteInstruction.js b/backend/endpoints/instruction/controller/deleteInstruction.js index 519c345..03c5318 100644 --- a/backend/endpoints/instruction/controller/deleteInstruction.js +++ b/backend/endpoints/instruction/controller/deleteInstruction.js @@ -11,38 +11,36 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id } = req.params; + const { id: rawInstructionId } = req.params; - // Check id - if (!id) { + // Check instruction id + if (rawInstructionId === undefined || rawInstructionId === null) { return res.status(400).json({ success: false, error: 'Missing instruction ID' }); } - if (typeof id !== 'string') { + if (typeof rawInstructionId !== 'string') { return res .status(400) .json({ success: false, error: 'The instruction ID provided is not a string' }); } - const sanitizedId = String(id).trim(); + const instructionId = rawInstructionId.trim(); - if (sanitizedId.length == 0) { + if (!instructionId) { return res.status(400).json({ success: false, error: 'The ID provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { + if (!ObjectId.isValid(instructionId)) { return res.status(400).json({ success: false, error: 'The ID provided is invalid' }); } // Delete instruction await db.collection('instruction').deleteOne({ - _id: new ObjectId(sanitizedId) + _id: new ObjectId(instructionId) }); // Delete all the methods associated with the instruction - await db.collection('method').deleteMany({ - instructionId: sanitizedId - }); + await db.collection('method').deleteMany({ instructionId }); return res.status(200).json({ success: true }); } catch (error) { diff --git a/backend/endpoints/instruction/controller/getAllInstructionsData.js b/backend/endpoints/instruction/controller/getAllInstructionsData.js index 7d92c94..2e6babf 100644 --- a/backend/endpoints/instruction/controller/getAllInstructionsData.js +++ b/backend/endpoints/instruction/controller/getAllInstructionsData.js @@ -11,28 +11,28 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id } = req.params || {}; + const { id: rawClusterId } = req.params || {}; - // Check id - if (!id) { + // Check cluster id + if (rawClusterId === undefined || rawClusterId === null) { return res.status(400).json({ success: false, error: 'Missing cluster ID' }); } - if (typeof id !== 'string') { + if (typeof rawClusterId !== 'string') { return res .status(400) .json({ success: false, error: 'The cluster ID provided is not a string' }); } - const sanitizedId = String(id).trim(); + const clusterId = rawClusterId.trim(); - if (sanitizedId.length === 0) { + if (!clusterId) { return res .status(400) .json({ success: false, error: 'The cluster ID provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { + if (!ObjectId.isValid(clusterId)) { return res.status(400).json({ success: false, error: 'Invalid cluster ID provided' }); } @@ -41,9 +41,7 @@ module.exports = (db) => { // Get all the instructions const instructions = await db .collection('instruction') - .find({ - clusterId: sanitizedId - }) + .find({ clusterId }) .toArray() .then((res) => res.map(({ _id, ...rest }) => ({ @@ -73,7 +71,6 @@ module.exports = (db) => { const methodData = m; methodData.id = m.id; delete methodData._id; - i.methods.push(methodData); }); diff --git a/backend/endpoints/instruction/controller/getAllInstructionsOnly.js b/backend/endpoints/instruction/controller/getAllInstructionsOnly.js index f1fa052..c04ac1c 100644 --- a/backend/endpoints/instruction/controller/getAllInstructionsOnly.js +++ b/backend/endpoints/instruction/controller/getAllInstructionsOnly.js @@ -11,28 +11,28 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id } = req.params || {}; + const { id: rawClusterId } = req.params || {}; - // Check id - if (!id) { + // Check cluster id + if (rawClusterId === undefined || rawClusterId === null) { return res.status(400).json({ success: false, error: 'Missing cluster ID' }); } - if (typeof id !== 'string') { + if (typeof rawClusterId !== 'string') { return res .status(400) .json({ success: false, error: 'The cluster ID provided is not a string' }); } - const sanitizedId = String(id).trim(); + const clusterId = rawClusterId.trim(); - if (sanitizedId.length === 0) { + if (!clusterId) { return res .status(400) .json({ success: false, error: 'The cluster Id provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { + if (!ObjectId.isValid(clusterId)) { return res.status(400).json({ success: false, error: 'Invalid cluster ID provided' }); } @@ -41,9 +41,7 @@ module.exports = (db) => { success: true, body: await db .collection('instruction') - .find({ - clusterId: sanitizedId - }) + .find({ clusterId }) .toArray() .then((res) => res diff --git a/backend/endpoints/instruction/controller/getInstructionsAllById.js b/backend/endpoints/instruction/controller/getInstructionsAllById.js index 5dd1399..acb114a 100644 --- a/backend/endpoints/instruction/controller/getInstructionsAllById.js +++ b/backend/endpoints/instruction/controller/getInstructionsAllById.js @@ -11,28 +11,28 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id } = req.params || {}; + const { id: rawInstructionId } = req.params || {}; - // Check id - if (!id) { + // Check instruction id + if (rawInstructionId === undefined || rawInstructionId === null) { return res.status(400).json({ success: false, error: 'Missing instruction id' }); } - if (typeof id !== 'string') { + if (typeof rawInstructionId !== 'string') { return res .status(400) .json({ success: false, error: 'The instruction id provided is not a string' }); } - const sanitizedId = String(id).trim(); + const instructionId = rawInstructionId.trim(); - if (sanitizedId.length === 0) { + if (!instructionId) { return res .status(400) .json({ success: false, error: 'The instruction id provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { + if (!ObjectId.isValid(instructionId)) { return res .status(400) .json({ success: false, error: 'Invalid instruction id provided' }); @@ -40,7 +40,7 @@ module.exports = (db) => { // Get the instruction const response = await db.collection('instruction').findOne({ - _id: new ObjectId(sanitizedId) + _id: new ObjectId(instructionId) }); if (!response) { @@ -52,27 +52,25 @@ module.exports = (db) => { response.methods = []; // Get methods for the instruction - const methods = await db + await db .collection('method') - .find({ - instructionId: response.id - }) + .find({ instructionId }) .toArray() - .then((result) => - result.map(({ _id, ...rest }) => ({ + .then((res) => + res.map(({ _id, ...rest }) => ({ id: _id.toString(), ...rest })) + ) + .then((res) => + res.forEach((m) => { + const methodData = m; + methodData.id = m.id; + delete methodData._id; + response.methods.push(methodData); + }) ); - methods.forEach((m) => { - const methodData = m; - methodData.id = m.id; - delete methodData._id; - - response.methods.push(methodData); - }); - return res .status(200) .json({ success: true, body: response.sort((a, b) => a.position - b.position) }); diff --git a/backend/endpoints/instruction/controller/getInstructionsOnlyById.js b/backend/endpoints/instruction/controller/getInstructionsOnlyById.js index fb1ecf5..327b581 100644 --- a/backend/endpoints/instruction/controller/getInstructionsOnlyById.js +++ b/backend/endpoints/instruction/controller/getInstructionsOnlyById.js @@ -11,28 +11,28 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id } = req.params || {}; + const { id: rawInstructionId } = req.params || {}; - // Check id - if (!id) { + // Check instruction id + if (rawInstructionId === undefined || rawInstructionId === null) { return res.status(400).json({ success: false, error: 'Missing instruction id' }); } - if (typeof id !== 'string') { + if (typeof rawInstructionId !== 'string') { return res .status(400) .json({ success: false, error: 'The instruction id provided is not a string' }); } - const sanitizedId = String(id).trim(); + const instructionId = rawInstructionId.trim(); - if (sanitizedId.length === 0) { + if (!instructionId) { return res .status(400) .json({ success: false, error: 'The instruction id provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { + if (!ObjectId.isValid(instructionId)) { return res .status(400) .json({ success: false, error: 'Invalid instruction id provided' }); @@ -40,7 +40,7 @@ module.exports = (db) => { // Get instruction const response = await db.collection('instruction').findOne({ - _id: new ObjectId(sanitizedId) + _id: new ObjectId(instructionId) }); if (!response) { diff --git a/backend/endpoints/instruction/controller/updateInstruction.js b/backend/endpoints/instruction/controller/updateInstruction.js index f2bd771..4bb1ce8 100644 --- a/backend/endpoints/instruction/controller/updateInstruction.js +++ b/backend/endpoints/instruction/controller/updateInstruction.js @@ -11,27 +11,27 @@ module.exports = (db) => { */ return async (req, res) => { try { - const { id, ...rest } = req.body || {}; + const { id: rawInstructionId, ...rest } = req.body || {}; - // Check id - if (!id) { - return res.status(400).json({ success: false, error: 'Missing instruction id' }); + // Check instruction id + if (rawInstructionId === undefined || rawInstructionId === null) { + return res.status(400).json({ success: false, error: 'Missing instruction ID' }); } if (typeof id !== 'string') { return res .status(400) - .json({ success: false, error: 'The instruction provided is not a string' }); + .json({ success: false, error: 'The instruction ID provided is not a string' }); } - const sanitizedId = String(id).trim(); + const instructionId = rawInstructionId.trim(); - if (sanitizedId.length == 0) { - return res.status(400).json({ success: false, error: 'The id provided is empty' }); + if (!instructionId) { + return res.status(400).json({ success: false, error: 'The instruction ID provided is empty' }); } - if (!ObjectId.isValid(sanitizedId)) { - return res.status(400).json({ success: false, error: 'The id provided is invalid' }); + if (!ObjectId.isValid(instructionId)) { + return res.status(400).json({ success: false, error: 'The instruction ID provided is invalid' }); } // Check updates @@ -48,7 +48,7 @@ module.exports = (db) => { // Check instruction exists const instructionExists = await db .collection('instruction') - .findOne({ _id: new ObjectId(sanitizedId) }); + .findOne({ _id: new ObjectId(instructionId) }); if (!instructionExists) { return res .status(404) @@ -71,7 +71,7 @@ module.exports = (db) => { .json({ success: false, error: 'The new instruction position is invalid' }); } - instructions = instructions.filter((i) => !i._id.equals(new ObjectId(id))); + instructions = instructions.filter((i) => !i._id.equals(new ObjectId(instructionId))); instructions.splice(updates.position - 1, 0, instructionExists); await db.collection('instruction').bulkWrite( @@ -90,7 +90,7 @@ module.exports = (db) => { // Do not remove this if the database validation will fail await db .collection('instruction') - .updateOne({ _id: new ObjectId(sanitizedId) }, { $set: updates }); + .updateOne({ _id: new ObjectId(instructionId) }, { $set: updates }); } return res.status(200).json({ success: true }); From 5235b2f3550161cf5d5bf6c3268ac92a85bf91c4 Mon Sep 17 00:00:00 2001 From: acegoal07 <39467245+acegoal07@users.noreply.github.com> Date: Wed, 8 Jul 2026 14:48:55 +0100 Subject: [PATCH 6/8] tweaks --- .../instruction/controller/addInstruction.js | 6 +- .../controller/updateInstruction.js | 19 +++--- backend/eslint.config.mjs | 2 +- frontend/app/components/ClusterSettings.jsx | 62 +++++++++++++++++-- frontend/app/components/Overview.jsx | 23 ++++--- frontend/app/components/TeamsSettingsPage.jsx | 5 +- frontend/eslint.config.mjs | 2 - 7 files changed, 88 insertions(+), 31 deletions(-) diff --git a/backend/endpoints/instruction/controller/addInstruction.js b/backend/endpoints/instruction/controller/addInstruction.js index 5f49d4d..14cc23a 100644 --- a/backend/endpoints/instruction/controller/addInstruction.js +++ b/backend/endpoints/instruction/controller/addInstruction.js @@ -20,6 +20,8 @@ module.exports = (db) => { bad: rawBad } = req.body || {}; + console.log(req.body); + // Check title if (rawTitle === undefined || rawTitle === null) { return res.status(400).json({ success: false, error: 'Missing instruction title' }); @@ -100,7 +102,7 @@ module.exports = (db) => { // Check good if (rawGood === undefined || rawGood === null) { - return res.status(400).json({ success: false, error: 'Missing instruction title' }); + return res.status(400).json({ success: false, error: 'Missing good' }); } if (typeof rawGood !== 'string') { @@ -117,7 +119,7 @@ module.exports = (db) => { // Check bad if (rawBad === undefined || rawBad === null) { - return res.status(400).json({ success: false, error: 'Missing instruction title' }); + return res.status(400).json({ success: false, error: 'Missing bad' }); } if (typeof rawBad !== 'string') { diff --git a/backend/endpoints/instruction/controller/updateInstruction.js b/backend/endpoints/instruction/controller/updateInstruction.js index 4bb1ce8..2eeb7bd 100644 --- a/backend/endpoints/instruction/controller/updateInstruction.js +++ b/backend/endpoints/instruction/controller/updateInstruction.js @@ -18,7 +18,7 @@ module.exports = (db) => { return res.status(400).json({ success: false, error: 'Missing instruction ID' }); } - if (typeof id !== 'string') { + if (typeof rawInstructionId !== 'string') { return res .status(400) .json({ success: false, error: 'The instruction ID provided is not a string' }); @@ -27,11 +27,15 @@ module.exports = (db) => { const instructionId = rawInstructionId.trim(); if (!instructionId) { - return res.status(400).json({ success: false, error: 'The instruction ID provided is empty' }); + return res + .status(400) + .json({ success: false, error: 'The instruction ID provided is empty' }); } if (!ObjectId.isValid(instructionId)) { - return res.status(400).json({ success: false, error: 'The instruction ID provided is invalid' }); + return res + .status(400) + .json({ success: false, error: 'The instruction ID provided is invalid' }); } // Check updates @@ -86,12 +90,9 @@ module.exports = (db) => { ); } - if (updates.length > 0) { - // Do not remove this if the database validation will fail - await db - .collection('instruction') - .updateOne({ _id: new ObjectId(instructionId) }, { $set: updates }); - } + await db + .collection('instruction') + .updateOne({ _id: new ObjectId(instructionId) }, { $set: updates }); return res.status(200).json({ success: true }); } catch (error) { diff --git a/backend/eslint.config.mjs b/backend/eslint.config.mjs index 76b33bf..4fd5a41 100644 --- a/backend/eslint.config.mjs +++ b/backend/eslint.config.mjs @@ -9,7 +9,7 @@ export default defineConfig([ { files: ['**/*.{js,mjs,cjs}'], languageOptions: { - sourceType: 'module', // ✅ FIX: allows import/export + sourceType: 'module', globals: { ...globals.node } diff --git a/frontend/app/components/ClusterSettings.jsx b/frontend/app/components/ClusterSettings.jsx index dd403e8..aeb99d6 100644 --- a/frontend/app/components/ClusterSettings.jsx +++ b/frontend/app/components/ClusterSettings.jsx @@ -7,7 +7,6 @@ import { useState, useEffect, useMemo, useCallback } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; import { FaDatabase, FaUser } from 'react-icons/fa'; import { IoIosArrowForward } from 'react-icons/io'; -import { Listbox, ListboxButton, ListboxOptions, ListboxOption } from '@headlessui/react'; export default function ClusterSettingsPage() { const searchParams = useSearchParams(); @@ -55,12 +54,16 @@ export default function ClusterSettingsPage() { const [editedInstructionTitle, setEditedInstructionTitle] = useState(''); const [editedInstructionDescription, setEditedInstructionDescription] = useState(''); const [editedInstructionExpectedTime, setEditedInstructionExpectedTime] = useState(''); + const [editedInstructionGood, setEditedInstructionGood] = useState(''); + const [editedInstructionBad, setEditedInstructionBad] = useState(''); const [editedInstructionPosition, setEditedInstructionPosition] = useState(0); const [addingInstruction, setAddingInstruction] = useState(false); const [newInstructionTitle, setNewInstructionTitle] = useState(''); const [newInstructionDescription, setNewInstructionDescription] = useState(''); const [newInstructionExpectedTime, setNewInstructionExpectedTime] = useState(''); + const [newInstructionGood, setNewInstructionGood] = useState(''); + const [newInstructionBad, setNewInstructionBad] = useState(''); const [reports, setReports] = useState([]); @@ -238,7 +241,7 @@ export default function ClusterSettingsPage() { } } - async function updateInstruction(id, title, description, expectedTime, position) { + async function updateInstruction(id, title, description, expectedTime, bad, good, position) { try { const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/instruction`, { method: 'PATCH', @@ -248,6 +251,8 @@ export default function ClusterSettingsPage() { title, description, expectedTime, + bad, + good, position }) }); @@ -270,9 +275,11 @@ export default function ClusterSettingsPage() { const title = newInstructionTitle.trim(); const description = newInstructionDescription.trim(); const expectedTime = newInstructionExpectedTime.trim(); + const good = newInstructionGood.trim(); + const bad = newInstructionBad.trim(); - if (!title || !description) { - alert('Title and description are required'); + if (!title || !description || !expectedTime || !good || !bad) { + alert('All inputs are required'); return; } @@ -283,7 +290,9 @@ export default function ClusterSettingsPage() { clusterId, title, description, - expectedTime + expectedTime, + good, + bad }) }); @@ -297,6 +306,8 @@ export default function ClusterSettingsPage() { setNewInstructionTitle(''); setNewInstructionDescription(''); setNewInstructionExpectedTime(''); + setNewInstructionGood(''); + setNewInstructionBad(''); } catch (err) { console.error(err); alert(err.message); @@ -481,6 +492,20 @@ export default function ClusterSettingsPage() { className="w-full rounded-xl border border-slate-700 bg-slate-900 p-3 text-white" /> + setNewInstructionGood(e.target.value)} + placeholder="Good outcome" + className="w-full rounded-xl border border-slate-700 bg-slate-900 p-3 text-white" + /> + + setNewInstructionBad(e.target.value)} + placeholder="Bad outcome" + className="w-full rounded-xl border border-slate-700 bg-slate-900 p-3 text-white" + /> +