diff --git a/backend/config/database/schema.sql b/backend/config/database/schema.sql index be774a469ce2b6829d16f9adb58213caccbeb4cd..436c633f923c5f804e955b98929f53dfa54bca60 100644 --- a/backend/config/database/schema.sql +++ b/backend/config/database/schema.sql @@ -79,7 +79,7 @@ CREATE TABLE IF NOT EXISTS peopleDegree ( degreeCollege VARCHAR(50), degreeYear VARCHAR(16), degreeDescription VARCHAR(255), - FOREIGN KEY (peopleId) REFERENCES people(peopleId), + FOREIGN KEY (peopleId) REFERENCES people(peopleId) ON DELETE CASCADE, FOREIGN KEY (degreeTypeId) REFERENCES degreeTypeLookup(degreeTypeId) ); @@ -92,7 +92,7 @@ CREATE TABLE IF NOT EXISTS peopleXAddress ( peopleId INT PRIMARY KEY, addressId INT UNIQUE, preferredAddress VARCHAR(255) NOT NULL, - FOREIGN KEY (peopleId) REFERENCES people(peopleId), + FOREIGN KEY (peopleId) REFERENCES people(peopleId) ON DELETE CASCADE, FOREIGN KEY (addressId) REFERENCES address(addressId) ); @@ -102,7 +102,7 @@ CREATE TABLE IF NOT EXISTS peopleContact ( contactNumber VARCHAR(255) NOT NULL, contactType VARCHAR(50) NOT NULL, preferredContact BOOLEAN NOT NULL DEFAULT FALSE, - FOREIGN KEY (peopleId) REFERENCES people(peopleId) + FOREIGN KEY (peopleId) REFERENCES people(peopleId) ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS involvementLookup ( @@ -115,7 +115,7 @@ CREATE TABLE IF NOT EXISTS peopleXInvolvement ( peopleId INT, involvementId INT, PRIMARY KEY (peopleId, involvementId), - FOREIGN KEY (peopleId) REFERENCES people(peopleId), + FOREIGN KEY (peopleId) REFERENCES people(peopleId) ON DELETE CASCADE, FOREIGN KEY (involvementId) REFERENCES involvementLookup(involvementId) ); diff --git a/backend/repository/peopleRepository.js b/backend/repository/peopleRepository.js index e530f051d99bd399a0a7ff86c67dbc1a1a86f7db..df0c1a37535190456236ed76c3447e0e130bb0e5 100644 --- a/backend/repository/peopleRepository.js +++ b/backend/repository/peopleRepository.js @@ -86,6 +86,32 @@ async function searchPeopleByName(firstName, lastName) { async function getPersonById() {} -async function deletePersonById() {} +/* +Function to delete a person with the peopleId given. +Since the SQL schema has ON DELETE CASCADE, all associated data +(address, contacts, etc). will also be deleted. Function returns +true if the delete was successful and false if not. +*/ +async function deletePersonById(peopleId) { + console.log("deleting person by id...."); + + try { + // execute the query to delete by primary key + const query = `DELETE FROM people WHERE peopleId = ?`; + const [results] = await pool.query(query, [peopleId]); + + // check if anything was deleted + if (results.affectedRows === 0) { + console.log("no rows deleted"); + return false; // no rows deleted + } + + console.log("row deleted"); + return true; + } catch (error) { + console.error(error); + return false; + } +} -module.exports = { addPerson, searchPeopleByName }; +module.exports = { addPerson, searchPeopleByName, deletePersonById }; diff --git a/backend/routes/peopleRoutes.js b/backend/routes/peopleRoutes.js index 7cf5d78e5014f9eff2962d7b278ebce965e987fb..9cf642ca842032eac1ce043d0b69d64b2ec5fb08 100644 --- a/backend/routes/peopleRoutes.js +++ b/backend/routes/peopleRoutes.js @@ -1,7 +1,11 @@ const { check, body, validationResult } = require("express-validator"); const express = require("express"); const peopleRouter = express.Router(); -const { createPerson, findByName } = require("../service/peopleService"); +const { + createPerson, + findByName, + deleteById, +} = require("../service/peopleService"); /* Function to check that the POST request body in create person contains the correct data types @@ -164,4 +168,36 @@ peopleRouter.post("/searchByName", async (req, res) => { } }); +// DELETE endpoint to delete a person by their ID +peopleRouter.delete("/:id", async (req, res) => { + const personId = parseInt(req.params.id, 10); // Convert to an integer + + // Check if personId is a valid integer + if (!Number.isInteger(personId)) { + return res + .status(400) + .json({ message: "Invalid ID. ID must be an integer." }); + } + + try { + // Call the function to delete the person + const success = await deleteById(personId); + + if (!success) { + // If no person is deleted, return a 404 status + return res + .status(404) + .json({ message: "Person not found or could not be deleted." }); + } + + // TODO: log database change here + + // Return a success message + res.json({ message: "Person successfully deleted." }); + } catch (error) { + console.error("Error in DELETE /person/:id", error); + res.status(500).json({ message: "Internal server error." }); + } +}); + module.exports = peopleRouter; diff --git a/backend/service/peopleService.js b/backend/service/peopleService.js index a5f813e358628bd376a1d7e8f2eccb32eb5a04eb..b0f9aabb9f1c3343bba207fe3ac812e2527606a3 100644 --- a/backend/service/peopleService.js +++ b/backend/service/peopleService.js @@ -4,6 +4,7 @@ const { addDegree } = require("../repository/degreeRepository"); const { addPerson, searchPeopleByName, + deletePersonById, } = require("../repository/peopleRepository"); /* @@ -56,4 +57,17 @@ async function findByName(firstName, lastName) { return peopleFound; } -module.exports = { createPerson, findByName }; +/* +Function to delete person by their id. +*/ +async function deleteById(peopleId) { + const personDeleted = await deletePersonById(peopleId); + + if (personDeleted) { + return true; + } + + return false; +} + +module.exports = { createPerson, findByName, deleteById };