From 911c498c2fca080fca2a27f6d7c87009ff77f3bb Mon Sep 17 00:00:00 2001 From: JordanChen123 Date: Thu, 30 Jan 2025 21:12:29 -0800 Subject: [PATCH 1/7] all post requests working, need to make changes to generic sensors though --- src/website/pages/api/aisships/index.ts | 39 ++++++++++++++++-- src/website/pages/api/batteries/index.ts | 33 +++++++++++++-- .../pages/api/generic-sensors/index.ts | 40 ++++++++++++++++--- src/website/pages/api/globalpath/index.ts | 33 +++++++++++++-- src/website/pages/api/gps/index.ts | 30 ++++++++++++-- src/website/pages/api/localpath/index.ts | 33 +++++++++++++-- src/website/pages/api/wind-sensors/index.ts | 33 +++++++++++++-- 7 files changed, 212 insertions(+), 29 deletions(-) diff --git a/src/website/pages/api/aisships/index.ts b/src/website/pages/api/aisships/index.ts index 9c2d0907c..4877d414c 100644 --- a/src/website/pages/api/aisships/index.ts +++ b/src/website/pages/api/aisships/index.ts @@ -21,13 +21,44 @@ export default async function handler( }); res.status(200).json({ success: true, data: aisships }); } catch (error) { - res - .status(400) - .json({ success: false, message: (error as Error).message }); + res.status(400).json({ success: false, message: (error as Error).message }); } break; + + case 'POST': + try { + const { ships, timestamp } = req.body; + + if (!Array.isArray(ships) || typeof timestamp !== 'string') { + return res.status(400).json({ success: false, message: "Invalid AISShips data format" }); + } + + for (const ship of ships) { + if ( + typeof ship.id !== 'number' || + typeof ship.latitude !== 'number' || + typeof ship.longitude !== 'number' || + typeof ship.cog !== 'number' || + typeof ship.rot !== 'number' || + typeof ship.sog !== 'number' || + typeof ship.width !== 'number' || + typeof ship.length !== 'number' + ) { + return res.status(400).json({ success: false, message: "Invalid ship object format" }); + } + } + + const newAISShips = new AISShips({ ships, timestamp }); + await newAISShips.save(); + + res.status(201).json({ success: true, message: "AISShips data stored", data: newAISShips }); + } catch (error) { + res.status(500).json({ success: false, message: (error as Error).message }); + } + break; + default: - res.status(400).json({ success: false }); + res.status(405).json({ success: false, message: "Method Not Allowed" }); break; } } diff --git a/src/website/pages/api/batteries/index.ts b/src/website/pages/api/batteries/index.ts index 0d310d2a6..a9cad7d14 100644 --- a/src/website/pages/api/batteries/index.ts +++ b/src/website/pages/api/batteries/index.ts @@ -20,13 +20,38 @@ export default async function handler( }); res.status(200).json({ success: true, data: batteries }); } catch (error) { - res - .status(400) - .json({ success: false, message: (error as Error).message }); + res.status(400).json({ success: false, message: (error as Error).message }); } break; + + case 'POST': + try { + const { batteries, timestamp } = req.body; + + if (!Array.isArray(batteries) || typeof timestamp !== 'string') { + return res.status(400).json({ success: false, message: "Invalid Batteries data format" }); + } + + for (const battery of batteries) { + if ( + typeof battery.voltage !== 'number' || + typeof battery.current !== 'number' + ) { + return res.status(400).json({ success: false, message: "Invalid battery object format" }); + } + } + + const newBatteries = new Batteries({ batteries, timestamp }); + await newBatteries.save(); + + res.status(201).json({ success: true, message: "Batteries data stored", data: newBatteries }); + } catch (error) { + res.status(500).json({ success: false, message: (error as Error).message }); + } + break; + default: - res.status(400).json({ success: false }); + res.status(405).json({ success: false, message: "Method Not Allowed" }); break; } } diff --git a/src/website/pages/api/generic-sensors/index.ts b/src/website/pages/api/generic-sensors/index.ts index 595a8ddaa..d6196ce95 100644 --- a/src/website/pages/api/generic-sensors/index.ts +++ b/src/website/pages/api/generic-sensors/index.ts @@ -18,15 +18,45 @@ export default async function handler( _id: 0, __v: 0, }); - res.status(200).json({ success: true, data: genericSensors }); + + const formattedData = genericSensors.map((entry) => ({ + ...entry.toObject(), + genericSensors: entry.genericSensors.map(sensor => ({ + id: sensor.id, + data: BigInt(sensor.data) + })) + })); + + res.status(200).json({ success: true, data: formattedData }); + } catch (error) { + res.status(400).json({ success: false, message: (error as Error).message }); + } + break; + + case 'POST': + try { + const { genericSensors, timestamp } = req.body; + + if (!Array.isArray(genericSensors) || typeof timestamp !== 'string') { + return res.status(400).json({ success: false, message: "Invalid GenericSensors data format" }); + } + + const processedSensors = genericSensors.map(sensor => ({ + id: sensor.id, + data: sensor.data.toString() + })); + + const newGenericSensors = new GenericSensors({ genericSensors: processedSensors, timestamp }); + await newGenericSensors.save(); + + res.status(201).json({ success: true, message: "GenericSensors data stored", data: newGenericSensors }); } catch (error) { - res - .status(400) - .json({ success: false, message: (error as Error).message }); + res.status(500).json({ success: false, message: (error as Error).message }); } break; + default: - res.status(400).json({ success: false }); + res.status(405).json({ success: false, message: "Method Not Allowed" }); break; } } diff --git a/src/website/pages/api/globalpath/index.ts b/src/website/pages/api/globalpath/index.ts index f7f88de70..1f22a21dd 100644 --- a/src/website/pages/api/globalpath/index.ts +++ b/src/website/pages/api/globalpath/index.ts @@ -21,13 +21,38 @@ export default async function handler( }); res.status(200).json({ success: true, data: gPath }); } catch (error) { - res - .status(400) - .json({ success: false, message: (error as Error).message }); + res.status(400).json({ success: false, message: (error as Error).message }); } break; + + case 'POST': + try { + const { waypoints, timestamp } = req.body; + + if (!Array.isArray(waypoints) || typeof timestamp !== 'string') { + return res.status(400).json({ success: false, message: "Invalid GlobalPath data format" }); + } + + for (const waypoint of waypoints) { + if ( + typeof waypoint.latitude !== 'number' || + typeof waypoint.longitude !== 'number' + ) { + return res.status(400).json({ success: false, message: "Invalid waypoint object format" }); + } + } + + const newGlobalPath = new GlobalPath({ waypoints, timestamp }); + await newGlobalPath.save(); + + res.status(201).json({ success: true, message: "GlobalPath data stored", data: newGlobalPath }); + } catch (error) { + res.status(500).json({ success: false, message: (error as Error).message }); + } + break; + default: - res.status(400).json({ success: false }); + res.status(405).json({ success: false, message: "Method Not Allowed" }); break; } } diff --git a/src/website/pages/api/gps/index.ts b/src/website/pages/api/gps/index.ts index 32880adeb..291ab8b7c 100644 --- a/src/website/pages/api/gps/index.ts +++ b/src/website/pages/api/gps/index.ts @@ -17,13 +17,35 @@ export default async function handler( const gps: GPSDocument[] = await GPS.find({}).select('-_id -__v'); res.status(200).json({ success: true, data: gps }); } catch (error) { - res - .status(400) - .json({ success: false, message: (error as Error).message }); + res.status(400).json({ success: false, message: (error as Error).message }); } break; + + case 'POST': + try { + const { latitude, longitude, speed, heading, timestamp } = req.body; + + if ( + typeof latitude !== 'number' || + typeof longitude !== 'number' || + typeof speed !== 'number' || + typeof heading !== 'number' || + typeof timestamp !== 'string' + ) { + return res.status(400).json({ success: false, message: "Invalid GPS data format" }); + } + + const newGPS = new GPS({ latitude, longitude, speed, heading, timestamp }); + await newGPS.save(); + + res.status(201).json({ success: true, message: "GPS data stored", data: newGPS }); + } catch (error) { + res.status(500).json({ success: false, message: (error as Error).message }); + } + break; + default: - res.status(400).json({ success: false }); + res.status(405).json({ success: false, message: "Method Not Allowed" }); break; } } diff --git a/src/website/pages/api/localpath/index.ts b/src/website/pages/api/localpath/index.ts index fd53ceb29..92a5fe690 100644 --- a/src/website/pages/api/localpath/index.ts +++ b/src/website/pages/api/localpath/index.ts @@ -21,13 +21,38 @@ export default async function handler( }); res.status(200).json({ success: true, data: localPath }); } catch (error) { - res - .status(400) - .json({ success: false, message: (error as Error).message }); + res.status(400).json({ success: false, message: (error as Error).message }); } break; + + case 'POST': + try { + const { waypoints, timestamp } = req.body; + + if (!Array.isArray(waypoints) || typeof timestamp !== 'string') { + return res.status(400).json({ success: false, message: "Invalid LocalPath data format" }); + } + + for (const waypoint of waypoints) { + if ( + typeof waypoint.latitude !== 'number' || + typeof waypoint.longitude !== 'number' + ) { + return res.status(400).json({ success: false, message: "Invalid waypoint object format" }); + } + } + + const newLocalPath = new LocalPath({ waypoints, timestamp }); + await newLocalPath.save(); + + res.status(201).json({ success: true, message: "LocalPath data stored", data: newLocalPath }); + } catch (error) { + res.status(500).json({ success: false, message: (error as Error).message }); + } + break; + default: - res.status(400).json({ success: false }); + res.status(405).json({ success: false, message: "Method Not Allowed" }); break; } } diff --git a/src/website/pages/api/wind-sensors/index.ts b/src/website/pages/api/wind-sensors/index.ts index 5b4ee7b86..e9909b44e 100644 --- a/src/website/pages/api/wind-sensors/index.ts +++ b/src/website/pages/api/wind-sensors/index.ts @@ -20,13 +20,38 @@ export default async function handler( }); res.status(200).json({ success: true, data: windSensors }); } catch (error) { - res - .status(400) - .json({ success: false, message: (error as Error).message }); + res.status(400).json({ success: false, message: (error as Error).message }); } break; + + case 'POST': + try { + const { windSensors, timestamp } = req.body; + + if (!Array.isArray(windSensors) || typeof timestamp !== 'string') { + return res.status(400).json({ success: false, message: "Invalid WindSensors data format" }); + } + + for (const sensor of windSensors) { + if ( + typeof sensor.speed !== 'number' || + typeof sensor.direction !== 'number' + ) { + return res.status(400).json({ success: false, message: "Invalid wind sensor object format" }); + } + } + + const newWindSensors = new WindSensors({ windSensors, timestamp }); + await newWindSensors.save(); + + res.status(201).json({ success: true, message: "WindSensors data stored", data: newWindSensors }); + } catch (error) { + res.status(500).json({ success: false, message: (error as Error).message }); + } + break; + default: - res.status(400).json({ success: false }); + res.status(405).json({ success: false, message: "Method Not Allowed" }); break; } } From 3acaf6c83c4e0c8e739e76f139310b0b0c91ca35 Mon Sep 17 00:00:00 2001 From: JordanChen123 Date: Wed, 12 Feb 2025 13:54:26 -0800 Subject: [PATCH 2/7] able to send generic sensor data in the right format --- .../pages/api/generic-sensors/index.ts | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/website/pages/api/generic-sensors/index.ts b/src/website/pages/api/generic-sensors/index.ts index d6196ce95..8828f9acd 100644 --- a/src/website/pages/api/generic-sensors/index.ts +++ b/src/website/pages/api/generic-sensors/index.ts @@ -19,15 +19,7 @@ export default async function handler( __v: 0, }); - const formattedData = genericSensors.map((entry) => ({ - ...entry.toObject(), - genericSensors: entry.genericSensors.map(sensor => ({ - id: sensor.id, - data: BigInt(sensor.data) - })) - })); - - res.status(200).json({ success: true, data: formattedData }); + res.status(200).json({ success: true, data: genericSensors }); } catch (error) { res.status(400).json({ success: false, message: (error as Error).message }); } @@ -43,7 +35,7 @@ export default async function handler( const processedSensors = genericSensors.map(sensor => ({ id: sensor.id, - data: sensor.data.toString() + data: typeof sensor.data === "bigint" ? sensor.data.toString() : sensor.data })); const newGenericSensors = new GenericSensors({ genericSensors: processedSensors, timestamp }); @@ -55,6 +47,15 @@ export default async function handler( } break; + case 'DELETE': + try { + await GenericSensors.deleteMany({}); + res.status(200).json({ success: true, message: "All GenericSensors data deleted" }); + } catch (error) { + res.status(500).json({ success: false, message: (error as Error).message }); + } + break; + default: res.status(405).json({ success: false, message: "Method Not Allowed" }); break; From e0d4dee1a3dc34f77bb5d5325abd37d678d8f2dc Mon Sep 17 00:00:00 2001 From: JordanChen123 Date: Wed, 5 Mar 2025 21:23:29 -0800 Subject: [PATCH 3/7] able to send multiple wavepoints at once, along with deleting --- src/website/pages/api/globalpath/index.ts | 38 +++++++++++++------ src/website/pages/api/gps/index.ts | 41 ++++++++++++++------- src/website/pages/api/localpath/index.ts | 45 ++++++++++++++++------- 3 files changed, 85 insertions(+), 39 deletions(-) diff --git a/src/website/pages/api/globalpath/index.ts b/src/website/pages/api/globalpath/index.ts index 1f22a21dd..54bbd1e8e 100644 --- a/src/website/pages/api/globalpath/index.ts +++ b/src/website/pages/api/globalpath/index.ts @@ -27,25 +27,39 @@ export default async function handler( case 'POST': try { - const { waypoints, timestamp } = req.body; + let globalPathData = req.body; - if (!Array.isArray(waypoints) || typeof timestamp !== 'string') { - return res.status(400).json({ success: false, message: "Invalid GlobalPath data format" }); + if (!Array.isArray(globalPathData)) { + globalPathData = [globalPathData]; } - for (const waypoint of waypoints) { - if ( - typeof waypoint.latitude !== 'number' || - typeof waypoint.longitude !== 'number' - ) { - return res.status(400).json({ success: false, message: "Invalid waypoint object format" }); + for (const entry of globalPathData) { + if (!Array.isArray(entry.waypoints) || typeof entry.timestamp !== 'string') { + return res.status(400).json({ success: false, message: "Invalid GlobalPath data format" }); + } + + for (const waypoint of entry.waypoints) { + if ( + typeof waypoint.latitude !== 'number' || + typeof waypoint.longitude !== 'number' + ) { + return res.status(400).json({ success: false, message: "Invalid waypoint object format" }); + } } } - const newGlobalPath = new GlobalPath({ waypoints, timestamp }); - await newGlobalPath.save(); + const newGlobalPaths = await GlobalPath.insertMany(globalPathData); + + res.status(201).json({ success: true, message: "GlobalPath data stored", data: newGlobalPaths }); + } catch (error) { + res.status(500).json({ success: false, message: (error as Error).message }); + } + break; - res.status(201).json({ success: true, message: "GlobalPath data stored", data: newGlobalPath }); + case 'DELETE': + try { + await GlobalPath.deleteMany({}); + res.status(200).json({ success: true, message: "All GlobalPath data cleared" }); } catch (error) { res.status(500).json({ success: false, message: (error as Error).message }); } diff --git a/src/website/pages/api/gps/index.ts b/src/website/pages/api/gps/index.ts index 291ab8b7c..77d9f09c9 100644 --- a/src/website/pages/api/gps/index.ts +++ b/src/website/pages/api/gps/index.ts @@ -23,22 +23,37 @@ export default async function handler( case 'POST': try { - const { latitude, longitude, speed, heading, timestamp } = req.body; - - if ( - typeof latitude !== 'number' || - typeof longitude !== 'number' || - typeof speed !== 'number' || - typeof heading !== 'number' || - typeof timestamp !== 'string' - ) { - return res.status(400).json({ success: false, message: "Invalid GPS data format" }); + let gpsData = req.body; + + if (!Array.isArray(gpsData)) { + gpsData = [gpsData]; + } + + for (const data of gpsData) { + const { latitude, longitude, speed, heading, timestamp } = data; + if ( + typeof latitude !== 'number' || + typeof longitude !== 'number' || + typeof speed !== 'number' || + typeof heading !== 'number' || + typeof timestamp !== 'string' + ) { + return res.status(400).json({ success: false, message: "Invalid GPS data format" }); + } } - const newGPS = new GPS({ latitude, longitude, speed, heading, timestamp }); - await newGPS.save(); + const newGPSData = await GPS.insertMany(gpsData); - res.status(201).json({ success: true, message: "GPS data stored", data: newGPS }); + res.status(201).json({ success: true, message: "GPS data stored", data: newGPSData }); + } catch (error) { + res.status(500).json({ success: false, message: (error as Error).message }); + } + break; + + case 'DELETE': + try { + await GPS.deleteMany({}); + res.status(200).json({ success: true, message: "All GPS data cleared" }); } catch (error) { res.status(500).json({ success: false, message: (error as Error).message }); } diff --git a/src/website/pages/api/localpath/index.ts b/src/website/pages/api/localpath/index.ts index 92a5fe690..7ddbe2ef8 100644 --- a/src/website/pages/api/localpath/index.ts +++ b/src/website/pages/api/localpath/index.ts @@ -14,12 +14,12 @@ export default async function handler( switch (method) { case 'GET': try { - const localPath: LocalPathDocument[] = await LocalPath.find({}).select({ + const localPaths: LocalPathDocument[] = await LocalPath.find({}).select({ 'waypoints._id': 0, _id: 0, __v: 0, }); - res.status(200).json({ success: true, data: localPath }); + res.status(200).json({ success: true, data: localPaths }); } catch (error) { res.status(400).json({ success: false, message: (error as Error).message }); } @@ -27,25 +27,42 @@ export default async function handler( case 'POST': try { - const { waypoints, timestamp } = req.body; + let localPathData = req.body; - if (!Array.isArray(waypoints) || typeof timestamp !== 'string') { - return res.status(400).json({ success: false, message: "Invalid LocalPath data format" }); + // If input is a single object, wrap it in an array + if (!Array.isArray(localPathData)) { + localPathData = [localPathData]; } - for (const waypoint of waypoints) { - if ( - typeof waypoint.latitude !== 'number' || - typeof waypoint.longitude !== 'number' - ) { - return res.status(400).json({ success: false, message: "Invalid waypoint object format" }); + // Validate each LocalPath entry + for (const entry of localPathData) { + if (!Array.isArray(entry.waypoints) || typeof entry.timestamp !== 'string') { + return res.status(400).json({ success: false, message: "Invalid LocalPath data format" }); + } + + for (const waypoint of entry.waypoints) { + if ( + typeof waypoint.latitude !== 'number' || + typeof waypoint.longitude !== 'number' + ) { + return res.status(400).json({ success: false, message: "Invalid waypoint object format" }); + } } } - const newLocalPath = new LocalPath({ waypoints, timestamp }); - await newLocalPath.save(); + // Insert LocalPath data + const newLocalPaths = await LocalPath.insertMany(localPathData); + + res.status(201).json({ success: true, message: "LocalPath data stored", data: newLocalPaths }); + } catch (error) { + res.status(500).json({ success: false, message: (error as Error).message }); + } + break; - res.status(201).json({ success: true, message: "LocalPath data stored", data: newLocalPath }); + case 'DELETE': + try { + await LocalPath.deleteMany({}); + res.status(200).json({ success: true, message: "All LocalPath data cleared" }); } catch (error) { res.status(500).json({ success: false, message: (error as Error).message }); } From 4a05dc33e2fd84534b639acc1ce6f53a22ca6bf8 Mon Sep 17 00:00:00 2001 From: JordanChen123 Date: Wed, 5 Mar 2025 21:27:21 -0800 Subject: [PATCH 4/7] removed comments --- src/website/pages/api/localpath/index.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/website/pages/api/localpath/index.ts b/src/website/pages/api/localpath/index.ts index 7ddbe2ef8..377b251d9 100644 --- a/src/website/pages/api/localpath/index.ts +++ b/src/website/pages/api/localpath/index.ts @@ -29,12 +29,10 @@ export default async function handler( try { let localPathData = req.body; - // If input is a single object, wrap it in an array if (!Array.isArray(localPathData)) { localPathData = [localPathData]; } - // Validate each LocalPath entry for (const entry of localPathData) { if (!Array.isArray(entry.waypoints) || typeof entry.timestamp !== 'string') { return res.status(400).json({ success: false, message: "Invalid LocalPath data format" }); @@ -50,7 +48,6 @@ export default async function handler( } } - // Insert LocalPath data const newLocalPaths = await LocalPath.insertMany(localPathData); res.status(201).json({ success: true, message: "LocalPath data stored", data: newLocalPaths }); From b0e299227e3e6d180b617ac3e7cedbc2b13d5fe4 Mon Sep 17 00:00:00 2001 From: JordanChen123 Date: Mon, 10 Mar 2025 23:45:49 -0700 Subject: [PATCH 5/7] test --- src/website/pages/api/globalpath/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/website/pages/api/globalpath/index.ts b/src/website/pages/api/globalpath/index.ts index 54bbd1e8e..45a347321 100644 --- a/src/website/pages/api/globalpath/index.ts +++ b/src/website/pages/api/globalpath/index.ts @@ -70,3 +70,4 @@ export default async function handler( break; } } +// \ No newline at end of file From 0c9404cb8e0881f02899a8b3103ba062e915f2ea Mon Sep 17 00:00:00 2001 From: JordanChen123 Date: Mon, 10 Mar 2025 23:47:05 -0700 Subject: [PATCH 6/7] test again --- src/website/pages/api/globalpath/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/website/pages/api/globalpath/index.ts b/src/website/pages/api/globalpath/index.ts index 45a347321..54bbd1e8e 100644 --- a/src/website/pages/api/globalpath/index.ts +++ b/src/website/pages/api/globalpath/index.ts @@ -70,4 +70,3 @@ export default async function handler( break; } } -// \ No newline at end of file From 9d738baac6983e4bac56206975575306db90655a Mon Sep 17 00:00:00 2001 From: JordanChen123 Date: Wed, 12 Mar 2025 14:05:56 -0700 Subject: [PATCH 7/7] no need to manually insert timestamps --- src/website/pages/api/globalpath/index.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/website/pages/api/globalpath/index.ts b/src/website/pages/api/globalpath/index.ts index 54bbd1e8e..f6f1bec12 100644 --- a/src/website/pages/api/globalpath/index.ts +++ b/src/website/pages/api/globalpath/index.ts @@ -33,9 +33,9 @@ export default async function handler( globalPathData = [globalPathData]; } - for (const entry of globalPathData) { - if (!Array.isArray(entry.waypoints) || typeof entry.timestamp !== 'string') { - return res.status(400).json({ success: false, message: "Invalid GlobalPath data format" }); + const processedPaths = globalPathData.map(entry => { + if (!Array.isArray(entry.waypoints)) { + throw new Error("Invalid GlobalPath data format"); } for (const waypoint of entry.waypoints) { @@ -43,16 +43,21 @@ export default async function handler( typeof waypoint.latitude !== 'number' || typeof waypoint.longitude !== 'number' ) { - return res.status(400).json({ success: false, message: "Invalid waypoint object format" }); + throw new Error("Invalid waypoint object format"); } } - } - const newGlobalPaths = await GlobalPath.insertMany(globalPathData); + return { + waypoints: entry.waypoints, + timestamp: entry.timestamp || new Date().toISOString() + }; + }); + + const newGlobalPaths = await GlobalPath.insertMany(processedPaths); res.status(201).json({ success: true, message: "GlobalPath data stored", data: newGlobalPaths }); } catch (error) { - res.status(500).json({ success: false, message: (error as Error).message }); + res.status(400).json({ success: false, message: error.message }); } break;