diff --git a/backend/config/auth/auth.login.js b/backend/config/auth/auth.login.js
index ebf5d6eaba54608c32e4e9c7706f429d03c832e0..be9e9710fc7632d5464a6ddd26d3638bdb6a05dc 100644
--- a/backend/config/auth/auth.login.js
+++ b/backend/config/auth/auth.login.js
@@ -1,9 +1,12 @@
 // library useful for development
 const passport = require("passport");
 const jwt = require("jsonwebtoken");
+const {
+  documentSuccessfulLogin,
+} = require("../../service/activityLoggerService");
 
 // function to handle the login process
-const casLogin = function (req, res, next) {
+const casLogin = async function (req, res, next) {
   console.log("Beginning log in....");
 
   // hard-coded for now.
@@ -13,6 +16,14 @@ const casLogin = function (req, res, next) {
   console.log("user: ", process.env.DB_USER);
 
   if (process.env.DB_USER === "corps_directory_dev") {
+    // document a successful login
+    try {
+      const timestamp = new Date(); // Current timestamp
+      await documentSuccessfulLogin(1, timestamp); // userID = 1 for now?
+    } catch (error) {
+      console.error("Error logging the successful login: ", error);
+    }
+
     // payload for the JWT token
     const payload = {
       id: 1,
@@ -32,7 +43,7 @@ const casLogin = function (req, res, next) {
   }
 
   // call the authenticate function with CAS
-  passport.authenticate("cas", function (err, user, info) {
+  passport.authenticate("cas", async function (err, user, info) {
     if (err) {
       console.log("found error during authentication: ", err);
       return next(err);
@@ -48,7 +59,7 @@ const casLogin = function (req, res, next) {
 
     // create a user object and redirect user
     // to the root route
-    req.logIn(user, function (err) {
+    req.logIn(user, async function (err) {
       console.log("Executing log in.");
       if (err) {
         return next(err);
@@ -64,6 +75,14 @@ const casLogin = function (req, res, next) {
       // sign the token with secret key
       const token = jwt.sign(payload, JWT_SECRET, { expiresIn: "1h" });
 
+      // document a successful login
+      try {
+        const timestamp = new Date(); // Current timestamp
+        await documentSuccessfulLogin(user.id, timestamp);
+      } catch (error) {
+        console.error("Error logging the successful login: ", error);
+      }
+
       // Send the JWT token to the frontend
       console.log("sending JWT To: ", process.env.FRONTEND_URL);
       res.redirect(`${process.env.FRONTEND_URL}/home?token=${token}`);
diff --git a/backend/config/database/schema.sql b/backend/config/database/schema.sql
index 3c1feccdc55660dc6e25738728cc0e6a2e9be70c..2ae7c243331f276eee89f85b69c5d5cd157ccf92 100644
--- a/backend/config/database/schema.sql
+++ b/backend/config/database/schema.sql
@@ -13,12 +13,11 @@ CREATE TABLE IF NOT EXISTS  users (
   FOREIGN KEY (roleID) REFERENCES rolesPermissions(roleID)
 );
 
--- Table to log login/logout information
-CREATE TABLE IF NOT EXISTS userLoginLogout (
+-- Table to log login information
+CREATE TABLE IF NOT EXISTS userLogin (
   eventId INT AUTO_INCREMENT PRIMARY KEY,
   eventTimestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
   userID INT NOT NULL, 
-  eventType VARCHAR(255) NOT NULL,   -- successfulLogin, unsuccessfulLogin, logout
   FOREIGN KEY (userID) REFERENCES users(userID)
 );
 
@@ -89,9 +88,10 @@ CREATE TABLE IF NOT EXISTS chapterLookup (
 );
 
 CREATE TABLE IF NOT EXISTS peopleXAddress (
-    peopleId INT PRIMARY KEY,
-    addressId INT UNIQUE,
+    peopleId INT,
+    addressId INT,
     preferredAddress VARCHAR(255) NOT NULL,
+    PRIMARY KEY (peopleId, addressId),
     FOREIGN KEY (peopleId) REFERENCES people(peopleId) ON DELETE CASCADE,
     FOREIGN KEY (addressId) REFERENCES address(addressId)
 );
@@ -119,8 +119,18 @@ CREATE TABLE IF NOT EXISTS peopleXInvolvement (
     FOREIGN KEY (involvementId) REFERENCES involvementLookup(involvementId)
 );
 
+CREATE TABLE IF NOT EXISTS changeLog (
+    logId INT PRIMARY KEY AUTO_INCREMENT,
+    changedTable VARCHAR(255) NOT NULL,   -- e.g., "people" to specify the table updated
+    recordId INT NOT NULL,                -- ID of the record that was updated
+    userId INT NOT NULL,                  -- User who made the change (foreign key to `users` table)
+    changeTimestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+    changeType ENUM('INSERT', 'UPDATE', 'DELETE') NOT NULL,
+    changedColumns TEXT NOT NULL,         -- Names of columns that were changed
+    oldValues TEXT,                       -- JSON format for previous values
+    newValues TEXT,                       -- JSON format for new values
+    FOREIGN KEY (userId) REFERENCES users(userID)
+);
+
 INSERT INTO countryLookup (countryId, name) 
 VALUES (1, 'United States');
-
--- I think there is already a people table that exists in our DB and 
--- has data that does not include peopoleID
\ No newline at end of file
diff --git a/backend/index.js b/backend/index.js
index 056453e40784243ab24898d5b41fb3a91faf2fe5..e571663e5ad0328388d8fe2f6192953877f1f843 100644
--- a/backend/index.js
+++ b/backend/index.js
@@ -3,6 +3,7 @@ const session = require("express-session");
 const cors = require("cors");
 require("dotenv").config();
 const userRoutes = require("./routes/userRoutes");
+const activityRouter = require("./routes/activityMonitoringRoutes");
 
 // create connection to db and initialize table schema
 const { pool } = require("./config/database/database.config");
@@ -49,6 +50,7 @@ app.use(function (req, res, next) {
 require("./config/auth/auth.routes")(app);
 app.use("/api/user", userRoutes);
 app.use("/api/person", peopleRouter);
+app.use("/api/activity", activityRouter);
 
 // Basic route to check if server is running
 app.get("/api", (req, res) => {
diff --git a/backend/repository/activityRepository.js b/backend/repository/activityRepository.js
new file mode 100644
index 0000000000000000000000000000000000000000..7cfefcd602145fe2a5eb59afde162bb4eb92088c
--- /dev/null
+++ b/backend/repository/activityRepository.js
@@ -0,0 +1,94 @@
+const { pool } = require("../config/database/database.config");
+
+/*
+Repository for login and changelog tables
+*/
+
+/*
+Add a row to the userLogin table indicating a successful 
+login.
+*/
+async function logSuccessfulLogin(userId, timestamp) {
+  try {
+    // SQL query to insert the login info
+    const query = `
+        INSERT INTO userLogin (eventTimestamp, userId) VALUES (?,?)
+    `;
+
+    // make query
+    const [result] = await pool.query(query, [timestamp, userId]);
+    console.log("Successfully logged log in.");
+
+    // return the inserted id
+    return result.insertId;
+  } catch (error) {
+    // throw error to be caught by the service
+    throw error;
+  }
+}
+
+async function getLoginDataTimerange(start, end) {
+  try {
+    // get all login data within the start and end timerange
+    const query = `
+      SELECT *
+      FROM userLogin
+      WHERE eventTimestamp BETWEEN ? AND ?
+      ORDER BY eventTimestamp DESC
+    `;
+    const [rows] = await pool.query(query, [start, end]);
+    return rows;
+  } catch (error) {
+    // throw error to be caught in service
+    console.error("Error fetching login data:", error);
+    throw error;
+  }
+}
+
+async function getLoginDataByUser() {}
+
+/*
+Insert a row into changeLog which keeps track of every time the database is changed.
+*/
+async function logDatabaseChange(
+  tableName,
+  recordId,
+  userId,
+  changeType,
+  changedColumns,
+  oldValues,
+  newValues
+) {
+  const query = `
+    INSERT INTO changeLog (changedTable, recordId, userId, changeType, changedColumns, oldValues, newValues)
+    VALUES (?, ?, ?, ?, ?, ?, ?)
+  `;
+  const values = [
+    tableName,
+    recordId,
+    userId,
+    changeType,
+    changedColumns,
+    oldValues,
+    newValues,
+  ];
+
+  try {
+    await pool.query(query, values);
+    console.log("Change logged successfully.");
+  } catch (error) {
+    // throw error to be caught by service
+    console.log("activity repository error when logging change: ", error);
+    throw error;
+  }
+}
+
+async function getDatabaseChangeTimerange() {}
+
+async function getDatabaseChangeByUser() {}
+
+module.exports = {
+  logSuccessfulLogin,
+  getLoginDataTimerange,
+  logDatabaseChange,
+};
diff --git a/backend/repository/addressRepository.js b/backend/repository/addressRepository.js
index 06da1ce87d9ea8966dea421bf50243733e54feb9..b0e8ee12836bd280f6ecf3de6a8897d86a69d67a 100644
--- a/backend/repository/addressRepository.js
+++ b/backend/repository/addressRepository.js
@@ -1,5 +1,5 @@
 const { pool } = require("../config/database/database.config");
-
+const { getStateId } = require("./stateRepository");
 /*
 Add address info into address table and peopleXaddress table
 */
@@ -12,7 +12,7 @@ async function addAddress(address, peopleId) {
 
   try {
     // Use helper functions to look up stateId and countryId
-    const stateId = await _lookupStateId(state);
+    const stateId = await getStateId(state);
     const countryId = await _lookupCountryId(country);
 
     // query for adding the address
@@ -62,48 +62,195 @@ async function addAddress(address, peopleId) {
   }
 }
 
-// Private helper function to look up the stateId
-async function _lookupStateId(state) {
-  // for now return 1 while tables are not populated
-  return 1;
+/*
+Function to update an address. If the address is successfully updated,
+the function returns the updated address's ID. If the address is not successfully
+updated, the function returns null
+*/
+async function updateAddress(addressId, peopleId, updatedAddress) {
+  // get the parts of the address
+  let { address1, address2, city, state, country, zipCode, preferredAddress } =
+    updatedAddress;
+
+  console.log("Updating address...");
+
+  try {
+    // look up the state and country
+    const stateId = await getStateId(state);
+    const countryId = await _lookupCountryId(country);
+
+    // Update the main address table
+    const updateAddressQuery = `
+      UPDATE address
+      SET address1 = ?, address2 = ?, city = ?, stateId = ?, countryId = ?, zipCode = ?
+      WHERE addressId = ?
+    `;
+    const [addressResult] = await pool.query(updateAddressQuery, [
+      address1,
+      address2,
+      city,
+      stateId,
+      countryId,
+      zipCode,
+      addressId,
+    ]);
+
+    // Check if any rows were updated in the address table
+    if (addressResult.affectedRows === 0) {
+      console.error("Address not found. No rows updated in the address table.");
+      return null;
+    }
+    console.log("Address table updated successfully.");
+
+    // Update the preferredAddress in peopleXAddress if provided
+    if (preferredAddress !== undefined) {
+      const updatePeopleXAddressQuery = `
+        UPDATE peopleXAddress
+        SET preferredAddress = ?
+        WHERE peopleId = ? AND addressId = ?
+      `;
+
+      const [peopleXAddressResult] = await pool.query(
+        updatePeopleXAddressQuery,
+        [preferredAddress, peopleId, addressId]
+      );
+
+      // Check if any rows were updated in the peopleXAddress table
+      if (peopleXAddressResult.affectedRows === 0) {
+        console.error(
+          "Associated record in peopleXAddress not found. No rows updated in the peopleXAddress table."
+        );
+        return null;
+      }
+
+      console.log("peopleXAddress table updated successfully.");
+    }
+
+    return addressId;
+  } catch (error) {
+    console.log("Error updating address: ", error);
+    return null;
+  }
+}
+
+/*
+Function to delete an address by its ID. 
+Deletes from both peopleXAddress and address tables.
+Returns true if the deletion was successful and false if no rows were affected.
+*/
+async function deleteAddressById(addressId) {
+  console.log("Deleting address with ID: ", addressId);
+
+  try {
+    // delete from the peopleXAddress table to satisfy any foreign key constraints
+    const deletePeopleXAddressQuery = `
+      DELETE FROM peopleXAddress
+      WHERE addressId = ?
+    `;
+    const [peopleXAddressResult] = await pool.query(deletePeopleXAddressQuery, [
+      addressId,
+    ]);
+
+    // Check if any rows were affected in peopleXAddress
+    if (peopleXAddressResult.affectedRows === 0) {
+      console.error(
+        "No associated record found in peopleXAddress. No rows deleted."
+      );
+      return false;
+    }
 
-  // try {
-  //   const lookupQuery = `
-  //     SELECT stateId FROM stateLookup WHERE name = ?
-  //   `;
-  //   const [lookupResults] = await pool.query(lookupQuery, [state]);
-
-  //   if (lookupResults.length === 0) {
-  //     console.log("State not found");
-  //     return null;
-  //   }
-
-  //   return lookupResults[0].stateId;
-  // } catch (error) {
-  //   console.error(`Error looking up state: ${state}`, error);
-  //   throw error;
-  // }
+    console.log("Deleted from peopleXAddress table");
+
+    // delete the address from the address table
+    const deleteAddressQuery = `
+      DELETE FROM address
+      WHERE addressId = ?
+    `;
+    const [addressResult] = await pool.query(deleteAddressQuery, [addressId]);
+
+    // Check if any rows were affected in the address table
+    if (addressResult.affectedRows === 0) {
+      console.error("Address not found in address table. No rows deleted.");
+      return false;
+    }
+
+    console.log("Address deleted successfully from address table.");
+
+    return true;
+  } catch (error) {
+    console.error("Error deleting address: ", error);
+    return false;
+  }
+}
+
+/*
+Function to find all address information associated with a person.
+Returns an array of address objects or an empty array if no addresses exist.
+*/
+async function getAddressesForPerson(peopleId) {
+  console.log("Finding addresses for person with ID: ", peopleId);
+
+  try {
+    const query = `
+      SELECT 
+        a.addressId, 
+        a.address1, 
+        a.address2, 
+        a.city, 
+        sl.name AS state, 
+        cl.name AS country, 
+        a.zipCode, 
+        pa.preferredAddress
+      FROM 
+        peopleXAddress pa
+      LEFT JOIN 
+        address a ON pa.addressId = a.addressId
+      LEFT JOIN 
+        stateLookup sl ON a.stateId = sl.stateId
+      LEFT JOIN 
+        countryLookup cl ON a.countryId = cl.countryId
+      WHERE 
+        pa.peopleId = ?;
+    `;
+
+    // Execute the query
+    const [results] = await pool.query(query, [peopleId]);
+
+    if (results.length === 0) {
+      console.log("No addresses found for person with ID:", peopleId);
+      return [];
+    }
+
+    // Map the results to structured address objects
+    const addresses = results.map((row) => ({
+      addressId: row.addressId,
+      address1: row.address1,
+      address2: row.address2,
+      city: row.city,
+      state: row.state,
+      country: row.country,
+      zipCode: row.zipCode,
+      preferredAddress: row.preferredAddress,
+    }));
+
+    console.log("Found addresses: ", addresses);
+
+    return addresses;
+  } catch (error) {
+    console.error("Error fetching addresses for person: ", error);
+    return [];
+  }
 }
 
 // Private helper function to look up the countryId
 async function _lookupCountryId(country) {
   // for now return 1 while tables are not populated
   return 1;
-
-  // try {
-  //   const lookupQuery = `
-  //     SELECT countryId FROM countryLookup WHERE name = ?
-  //   `;
-  //   const [lookupResults] = await pool.query(lookupQuery, [country]);
-  //   if (lookupResults.length === 0) {
-  //     console.log("Country not found");
-  //     return null;
-  //   }
-  //   return lookupResults[0].countryId;
-  // } catch (error) {
-  //   console.error(`Error looking up country: ${country}`, error);
-  //   throw error;
-  // }
 }
 
-module.exports = { addAddress };
+module.exports = {
+  addAddress,
+  getAddressesForPerson,
+  deleteAddressById,
+  updateAddress,
+};
diff --git a/backend/repository/contactRepository.js b/backend/repository/contactRepository.js
index 0a091e928f1acd8ce88d4086d3d3303580685cae..72247593391cc356fe1dccd80bc37e2514a772f1 100644
--- a/backend/repository/contactRepository.js
+++ b/backend/repository/contactRepository.js
@@ -2,7 +2,8 @@ const { pool } = require("../config/database/database.config");
 
 /*
 Function to add a row into the peopleContact
-table with the contact info given
+table with the contact info given. Returns the id of the new contact.
+If no contact is added, null is returned
 */
 async function addContact(contact, peopleId) {
   // extract the parts of the contact
@@ -25,11 +26,135 @@ async function addContact(contact, peopleId) {
       preferredContact,
     ]);
 
-    return results;
+    return results.insertId;
   } catch (error) {
     console.log(error);
     return null;
   }
 }
 
-module.exports = { addContact };
+/*
+Function to update the data for a specific contact. The 
+function will return true if the update was successful and false
+otherwise.
+*/
+async function updateContact(peopleContactId, peopleId, contactInfo) {
+  // extract the parts of the contact
+  let { contactNumber, contactType, preferredContact } = contactInfo;
+
+  console.log("updating contact....");
+
+  try {
+    const query = `
+        UPDATE peopleContact
+        SET
+          peopleId = ?,
+          contactNumber = ?,
+          contactType = ?,
+          preferredContact = ?
+        WHERE peopleContactId = ?
+      `;
+
+    const [results] = await pool.query(query, [
+      peopleId,
+      contactNumber,
+      contactType,
+      preferredContact,
+      peopleContactId,
+    ]);
+
+    // Check if any rows were affected
+    if (results.affectedRows === 0) {
+      console.error("Contact not found. no rows updated");
+      return false;
+    }
+
+    // return true to signify success
+    return true;
+  } catch (error) {
+    console.log("Error updating contact: ", error);
+    return false;
+  }
+}
+
+/*
+Function to find all contact information associated with a person.
+Returns an array of contact objects or an empty array if no contacts exist.
+*/
+async function getContactsForPerson(peopleId) {
+  console.log("Finding contacts for person with ID: ", peopleId);
+
+  try {
+    // get all contacts with the wanted peopleId
+    const query = `
+      SELECT 
+        peopleContactId, 
+        contactNumber, 
+        contactType, 
+        preferredContact
+      FROM 
+        peopleContact
+      WHERE 
+        peopleId = ?;
+    `;
+
+    // Execute the query
+    const [results] = await pool.query(query, [peopleId]);
+
+    if (results.length === 0) {
+      console.log("No contacts found for person with ID:", peopleId);
+      return []; // empty array, no contacts found
+    }
+
+    // Map the results to structured contact objects
+    const contacts = results.map((row) => ({
+      peopleContactId: row.peopleContactId,
+      contactNumber: row.contactNumber,
+      contactType: row.contactType,
+      preferredContact: row.preferredContact,
+    }));
+
+    console.log("Found contacts: ", contacts);
+
+    return contacts;
+  } catch (error) {
+    console.error("Error fetching contacts for person: ", error);
+    return []; // empty array, no contacts found
+  }
+}
+
+/*
+Function to delete a contact by its ID. 
+Returns true if the deletion was successful and false if no rows were affected.
+*/
+async function deleteContactById(peopleContactId) {
+  console.log("Deleting contact with ID: ", peopleContactId);
+
+  try {
+    const query = `
+      DELETE FROM peopleContact
+      WHERE peopleContactId = ?
+    `;
+
+    const [results] = await pool.query(query, [peopleContactId]);
+
+    // Check if any rows were affected
+    if (results.affectedRows === 0) {
+      console.error("Contact not found. No rows deleted.");
+      return false;
+    }
+
+    console.log("Contact deleted successfully.");
+    return true;
+  } catch (error) {
+    console.error("Error deleting contact: ", error);
+    return false;
+  }
+}
+
+module.exports = {
+  addContact,
+  updateContact,
+  getContactsForPerson,
+  deleteContactById,
+};
diff --git a/backend/repository/degreeRepository.js b/backend/repository/degreeRepository.js
index 9e7835f6df78a84ca076cbe753c0fabfcf5efb23..1c3dda1e84c39358dd7e3b8ecea1dbf7d3f31509 100644
--- a/backend/repository/degreeRepository.js
+++ b/backend/repository/degreeRepository.js
@@ -1,7 +1,8 @@
 const { pool } = require("../config/database/database.config");
 
 /*
-Add degree information into the database.
+Add degree information into the database. The method will return 
+the id of the newly inserted degree, or null if nothing was added.
 */
 async function addDegree(degree, peopleId) {
   // get all the parts of the degree
@@ -35,7 +36,14 @@ async function addDegree(degree, peopleId) {
       degreeDescription,
     ]);
 
-    return results;
+    console.log("Inserted degree: ", results.insertId);
+
+    const checkQuery = `SELECT * FROM peopleDegree WHERE peopleDegreeId = ?`;
+    const [checkResults] = await pool.query(checkQuery, [results.insertId]);
+
+    console.log(checkResults[0]);
+
+    return results.insertId;
   } catch (error) {
     // return null if there is an error
     console.error(error);
@@ -43,28 +51,194 @@ async function addDegree(degree, peopleId) {
   }
 }
 
+/*
+Function to update the information about a specific degree 
+in the database. The function will return true if a row
+was successfully updated and false otherwise.
+*/
+async function updateDegree(peopleDegreeId, peopleId, degreeInfo) {
+  console.log("updating degree....");
+
+  // get all the parts of the degree
+  let {
+    degreeType,
+    degreeDepartment,
+    degreeCollege,
+    degreeYear,
+    degreeDescription,
+  } = degreeInfo;
+
+  try {
+    // Use the helper function to determine the degreeTypeId
+    let degreeTypeId = await _lookupDegreeTypeId(degreeType);
+
+    // SQL query to update
+    const query = `
+      UPDATE peopleDegree
+      SET
+        peopleId = ?,
+        degreeTypeId = ?,
+        degreeDepartment = ?,
+        degreeCollege = ?, 
+        degreeYear = ?,
+        degreeDescription = ?
+      WHERE peopleDegreeId = ?
+    `;
+
+    const [results] = await pool.query(query, [
+      peopleId,
+      degreeTypeId,
+      degreeDepartment,
+      degreeCollege,
+      degreeYear,
+      degreeDescription,
+      peopleDegreeId,
+    ]);
+
+    // Check if any rows were affected
+    if (results.affectedRows === 0) {
+      console.error("Degree not found. no rows updated");
+      return false;
+    }
+
+    console.log("degree info updated: ", peopleDegreeId);
+
+    // return true to signify success
+    return true;
+  } catch (error) {
+    console.error("error updating degree: ", error);
+    return false;
+  }
+}
+
+/*
+Function to delete a degree by its ID. 
+Returns true if the degree was successfully deleted, false otherwise.
+*/
+async function deleteDegreeById(peopleDegreeId) {
+  console.log("Deleting degree with ID: ", peopleDegreeId);
+
+  try {
+    const query = `
+      DELETE FROM peopleDegree
+      WHERE peopleDegreeId = ?
+    `;
+
+    const [results] = await pool.query(query, [peopleDegreeId]);
+
+    // Check if any rows were affected
+    if (results.affectedRows === 0) {
+      console.error("Degree not found. No rows deleted.");
+      return false;
+    }
+
+    console.log("Degree successfully deleted: ", peopleDegreeId);
+
+    return true;
+  } catch (error) {
+    console.error("Error deleting degree: ", error);
+    return false;
+  }
+}
+
+/*
+Function to find all degree IDs associated with a person. 
+Returns an array of peopleDegreeIds or an empty array if no degrees exist.
+*/
+async function getDegreeIdsForPerson(peopleId) {
+  console.log("Finding degree IDs for person with ID: ", peopleId);
+
+  try {
+    // get the degrees for a given peopleId
+    const query = `
+      SELECT peopleDegreeId 
+      FROM peopleDegree
+      WHERE peopleId = ?
+    `;
+
+    const [results] = await pool.query(query, [peopleId]);
+
+    // Extract the degree IDs
+    const degreeIds = results.map((row) => row.peopleDegreeId);
+
+    console.log("Found degree IDs: ", degreeIds);
+
+    return degreeIds;
+  } catch (error) {
+    console.error("Error finding degree IDs: ", error);
+    return [];
+  }
+}
+
+/*
+Function to get all degree information associated with a person.
+Returns an array of degree objects or an empty array if no degrees exist.
+*/
+async function getDegreesForPerson(peopleId) {
+  console.log("Finding degrees for person with ID: ", peopleId);
+
+  try {
+    // get the full degree information for degreees for person with peopleId
+    const query = `
+      SELECT 
+        d.peopleDegreeId, 
+        d.degreeDepartment, 
+        d.degreeCollege, 
+        d.degreeYear, 
+        d.degreeDescription, 
+        dt.degreeType
+      FROM 
+        peopleDegree d
+      LEFT JOIN 
+        degreeTypeLookup dt ON d.degreeTypeId = dt.degreeTypeId
+      WHERE 
+        d.peopleId = ?;
+    `;
+
+    const [results] = await pool.query(query, [peopleId]);
+
+    // Print out each row returned by the query
+    console.log("Raw results from query:", results);
+
+    if (results.length === 0) {
+      console.log("No degrees found for person with ID:", peopleId);
+      return [];
+    }
+
+    const degrees = results.map((row) => ({
+      peopleDegreeId: row.peopleDegreeId,
+      degreeType: row.degreeType,
+      degreeDepartment: row.degreeDepartment,
+      degreeCollege: row.degreeCollege,
+      degreeYear: row.degreeYear,
+      degreeDescription: row.degreeDescription,
+    }));
+
+    console.log("Found degrees: ", degrees);
+
+    return degrees;
+  } catch (error) {
+    console.error("Error fetching degrees for person: ", error);
+    return [];
+  }
+}
+
 // Private helper function to look up the degreeTypeId
 async function _lookupDegreeTypeId(degreeType) {
   try {
     // return null for now
     return null;
-
-    // const lookupQuery = `
-    //   SELECT degreeTypeId FROM degreeTypeLookup WHERE degreeType = ?
-    // `;
-    // const [lookupResults] = await pool.query(lookupQuery, [degreeType]);
-
-    // if (lookupResults.length === 0) {
-    //   console.log("Degree type not found");
-    //   return null;
-    //   // throw new Error(`Invalid degree type: ${degreeType}`);
-    // }
-
-    // return lookupResults[0].degreeTypeId;
   } catch (error) {
     console.error(`Error looking up degree type: ${degreeType}`, error);
     throw error;
   }
 }
 
-module.exports = { addDegree, _lookupDegreeTypeId };
+module.exports = {
+  addDegree,
+  updateDegree,
+  deleteDegreeById,
+  getDegreeIdsForPerson,
+  getDegreesForPerson,
+  _lookupDegreeTypeId,
+};
diff --git a/backend/repository/peopleRepository.js b/backend/repository/peopleRepository.js
index df0c1a37535190456236ed76c3447e0e130bb0e5..59dda80f2d70b9bdde1d78737ea05a2bf3a9666b 100644
--- a/backend/repository/peopleRepository.js
+++ b/backend/repository/peopleRepository.js
@@ -84,7 +84,54 @@ async function searchPeopleByName(firstName, lastName) {
   }
 }
 
-async function getPersonById() {}
+/*
+Function to get the data associated with a specific peopleId.
+If none is found, the function returns null.
+*/
+async function getPersonById(peopleId) {
+  console.log("searching for person...");
+
+  try {
+    // big query to get all of the data
+    const query = `
+    SELECT 
+      peopleId, 
+      firstName, 
+      lastName, 
+      middleName, 
+      maidenName, 
+      suffix, 
+      nickName, 
+      techAlumniChapter, 
+      classYear, 
+      gradYear, 
+      gradSemester, 
+      gender
+    FROM 
+      people
+    WHERE 
+      peopleId = ?;
+  `;
+
+    // Execute the query
+    const [rows] = await pool.query(query, [peopleId]);
+
+    if (rows.length === 0) {
+      console.log("No person found");
+      null;
+    }
+
+    // structure the data
+    console.log("data recieved... structuring now");
+
+    // create the structure of a person
+    const person = rows[0];
+    return person;
+  } catch (error) {
+    console.log("Error getting person's full details: ", error);
+    return null;
+  }
+}
 
 /*
 Function to delete a person with the peopleId given. 
@@ -107,6 +154,82 @@ async function deletePersonById(peopleId) {
     }
 
     console.log("row deleted");
+
+    return true;
+  } catch (error) {
+    console.error(error);
+    return false;
+  }
+}
+
+/*
+Function to update the people table's information for
+the person with the given id.
+*/
+async function updatePerson(personId, personInfo) {
+  // extract all the values from person
+  let {
+    firstName,
+    lastName,
+    middleName,
+    maidenName,
+    suffix,
+    nickName,
+    techAlumniChapter,
+    classYear,
+    gradYear,
+    gradSemester,
+    gender,
+  } = personInfo;
+
+  // find the integer that represents the alumni chapter (for now do 2)
+  techAlumniChapter = 2;
+
+  try {
+    console.log("Updating person: ", firstName);
+
+    // SQL UPDATE query
+    const query = `
+     UPDATE people
+     SET 
+       firstName = ?, 
+       lastName = ?, 
+       middleName = ?, 
+       maidenName = ?, 
+       suffix = ?, 
+       nickName = ?, 
+       techAlumniChapter = ?, 
+       classYear = ?, 
+       gradYear = ?, 
+       gradSemester = ?, 
+       gender = ?
+     WHERE peopleId = ?
+   `;
+
+    const [results] = await pool.query(query, [
+      firstName,
+      lastName,
+      middleName,
+      maidenName,
+      suffix,
+      nickName,
+      techAlumniChapter,
+      classYear,
+      gradYear,
+      gradSemester,
+      gender,
+      personId,
+    ]);
+
+    // Check if any rows were affected
+    if (results.affectedRows === 0) {
+      console.error("Person not found. no rows updated");
+      return false;
+    }
+
+    console.log("person info updated: ", personId);
+
+    // return true to signify success
     return true;
   } catch (error) {
     console.error(error);
@@ -114,4 +237,10 @@ async function deletePersonById(peopleId) {
   }
 }
 
-module.exports = { addPerson, searchPeopleByName, deletePersonById };
+module.exports = {
+  addPerson,
+  searchPeopleByName,
+  deletePersonById,
+  updatePerson,
+  getPersonById,
+};
diff --git a/backend/repository/stateRepository.js b/backend/repository/stateRepository.js
index 14e489d053bf2320fae6ef639ef9f320cc51e946..15dd0801155fb2c4f002397a3f11d18861da1832 100644
--- a/backend/repository/stateRepository.js
+++ b/backend/repository/stateRepository.js
@@ -53,7 +53,27 @@ async function getState(name) {
   }
 }
 
-async function checkStateTableExistence() {
+async function getStateId(name) {
+  // SQL query to get a certain state id
+  const query = "SELECT stateId FROM stateLookup WHERE name = ?";
+
+  try {
+    console.log("Getting state: ", name);
+    const [rows] = await pool.query(query, [name]);
+    if (rows.length > 0) {
+      console.log("Found state: ", name);
+      return rows[0];
+    } else {
+      console.log("State not found: ", name);
+      return null;
+    }
+  } catch (error) {
+    console.error(`Error fetching state with ID ${name}:`, error);
+    throw error;
+  }
+}
+
+async function checkTableExistence() {
   try {
     const [rows] = await pool.query("SHOW TABLES LIKE 'stateLookup'");
     if (rows.length > 0) {
@@ -66,4 +86,9 @@ async function checkStateTableExistence() {
   }
 }
 
-module.exports = { checkStateTableExistence, addStateIfNotExists, getState };
+module.exports = {
+  checkTableExistence,
+  addStateIfNotExists,
+  getState,
+  getStateId,
+};
diff --git a/backend/routes/activityMonitoringRoutes.js b/backend/routes/activityMonitoringRoutes.js
new file mode 100644
index 0000000000000000000000000000000000000000..17d4c1f0e6454570c3e1cb44c5d20253d859c273
--- /dev/null
+++ b/backend/routes/activityMonitoringRoutes.js
@@ -0,0 +1,28 @@
+const express = require("express");
+const { viewLoginsTimerange } = require("../service/activityLoggerService");
+
+const activityRouter = express.Router();
+
+// get login history by timerange
+activityRouter.get("/login-data", async (req, res) => {
+  const { start, end } = req.query;
+
+  // ensure both params are given
+  if (!start || !end) {
+    return res
+      .status(400)
+      .json({ message: "Please provide both start and end dates." });
+  }
+
+  try {
+    const data = await viewLoginsTimerange(start, end);
+    res.status(200).json(data);
+  } catch {
+    console.log("error fetching login data: ", error);
+    res.status(500).json({ message: "Internal service error." });
+  }
+});
+
+// get db history for timerange
+
+module.exports = activityRouter;
diff --git a/backend/routes/peopleRoutes.js b/backend/routes/peopleRoutes.js
index 9cf642ca842032eac1ce043d0b69d64b2ec5fb08..c9c22276affa904d5b1118df64e16c65a1e2d312 100644
--- a/backend/routes/peopleRoutes.js
+++ b/backend/routes/peopleRoutes.js
@@ -5,6 +5,8 @@ const {
   createPerson,
   findByName,
   deleteById,
+  updatePersonById,
+  getPersonFullDetails,
 } = require("../service/peopleService");
 /*
 Function to check that the POST request body in 
@@ -200,4 +202,58 @@ peopleRouter.delete("/:id", async (req, res) => {
   }
 });
 
+peopleRouter.put("/update/:id", async (req, res) => {
+  // get the personId from the URL params
+  const personId = parseInt(req.params.id, 10);
+
+  // 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 update service
+    console.log("req.body: ", req.body);
+    const success = await updatePersonById(personId, req.body);
+
+    // no person was updated
+    if (!success) {
+      return res.status(404).json({ message: "Person not found" });
+    }
+
+    return res
+      .status(200)
+      .json({ message: "Person updated successfully", personId });
+  } catch (error) {
+    console.error("Error in PUT /update/:id", error);
+    return res.status(500).json({ message: "Internal server error" });
+  }
+});
+
+peopleRouter.get("/fullInfo/:id", async (req, res) => {
+  // get the personId from the URL params
+  const personId = parseInt(req.params.id, 10);
+
+  // 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 {
+    const person = await getPersonFullDetails(personId);
+
+    if (person == null) {
+      return res.status(404).json({ message: "Person not found" });
+    }
+
+    return res.status(200).json({ message: "Person found", person });
+  } catch (error) {
+    console.error("Error in GET /fullInfo/:id", error);
+    return res.status(500).json({ message: "Internal server error" });
+  }
+});
 module.exports = peopleRouter;
diff --git a/backend/service/activityLoggerService.js b/backend/service/activityLoggerService.js
new file mode 100644
index 0000000000000000000000000000000000000000..9fa3a89b4a3b22ec7d12a49ac14dbe23ba50fa66
--- /dev/null
+++ b/backend/service/activityLoggerService.js
@@ -0,0 +1,44 @@
+const {
+  logSuccessfulLogin,
+  getLoginDataTimerange,
+  logDatabaseChange,
+} = require("../repository/activityRepository");
+
+/*
+Function that creates a row of data in the userLogin table 
+to documenmt a successful log in.
+*/
+async function documentSuccessfulLogin(userId, timestamp) {
+  try {
+    const result = await logSuccessfulLogin(userId, timestamp);
+  } catch (error) {
+    // SQL error from the repository
+    console.log("Error when logging a successful login: ", error);
+  }
+}
+
+async function logDatabaseChange(
+  tableName,
+  recordId,
+  userId,
+  changeType,
+  changedColumns,
+  oldValues,
+  newValues
+) {}
+
+/*
+Get the login data for a sopecific time range
+*/
+async function viewLoginsTimerange(start, end) {
+  // will throw error if there is a problem
+  return await getLoginDataTimerange(start, end);
+}
+
+async function viewDatabaseChanges() {}
+
+module.exports = {
+  documentSuccessfulLogin,
+  viewLoginsTimerange,
+  logDatabaseChange,
+};
diff --git a/backend/service/peopleService.js b/backend/service/peopleService.js
index b0f9aabb9f1c3343bba207fe3ac812e2527606a3..10b760c4ac84705ffb8d48a037c23ac8ab10e1d8 100644
--- a/backend/service/peopleService.js
+++ b/backend/service/peopleService.js
@@ -1,10 +1,28 @@
-const { addAddress } = require("../repository/addressRepository");
-const { addContact } = require("../repository/contactRepository");
-const { addDegree } = require("../repository/degreeRepository");
+const {
+  addAddress,
+  getAddressesForPerson,
+  deleteAddressById,
+  updateAddress,
+} = require("../repository/addressRepository");
+const {
+  addContact,
+  getContactsForPerson,
+  updateContact,
+  deleteContactById,
+} = require("../repository/contactRepository");
+const {
+  addDegree,
+  getDegreeIdsForPerson,
+  deleteDegreeById,
+  updateDegree,
+  getDegreesForPerson,
+} = require("../repository/degreeRepository");
 const {
   addPerson,
   searchPeopleByName,
   deletePersonById,
+  updatePerson,
+  getPersonById,
 } = require("../repository/peopleRepository");
 
 /*
@@ -22,19 +40,19 @@ async function createPerson(person) {
   // insert the degree information into the database
   for (const degree of degrees) {
     const addedDegree = await addDegree(degree, newPersonID);
-    console.log("added degree: ", degree);
+    console.log("added degree: ", addedDegree);
   }
 
   // insert the address information into the database
   for (const address of addresses) {
     const addedAddress = await addAddress(address, newPersonID);
-    console.log("added address: ", address);
+    console.log("added address: ", addedAddress);
   }
 
   // insert the contact information into the database
   for (const contact of contacts) {
     const addedContact = await addContact(contact, newPersonID);
-    console.log("added contact: ", contact);
+    console.log("added contact: ", addedContact);
   }
 
   // insert the involvment information into the database
@@ -61,6 +79,7 @@ async function findByName(firstName, lastName) {
 Function to delete person by their id.
 */
 async function deleteById(peopleId) {
+  // delete the person
   const personDeleted = await deletePersonById(peopleId);
 
   if (personDeleted) {
@@ -70,4 +89,191 @@ async function deleteById(peopleId) {
   return false;
 }
 
-module.exports = { createPerson, findByName, deleteById };
+/*
+Function to update all of a person with the given id's information.
+*/
+async function updatePersonById(personId, person) {
+  console.log("Person: ", person);
+
+  const { personInfo, degrees, addresses, contacts, involvements } = person;
+
+  console.log("Updating person...");
+
+  // update personInfo
+  const updatedPersonInfo = await updatePerson(personId, personInfo);
+  if (updatedPersonInfo == false) {
+    return null;
+  }
+
+  console.log("updated person info");
+
+  // update degrees
+  if (degrees) {
+    await updateDegreesForPerson(personId, degrees);
+  }
+
+  // update address info
+  if (addresses) {
+    await updateAddressesForPerson(personId, addresses);
+  }
+
+  // update contact info
+  if (contacts) {
+    await updateContactsForPerson(personId, contacts);
+  }
+
+  if (involvements) {
+    await updateInvolvementsForPerson(personId, involvements);
+  }
+  return true;
+}
+
+/*
+Function to get all the data that is associated with a single 
+person.
+*/
+async function getPersonFullDetails(personId) {
+  // get the personal details
+  const personalInformation = await getPersonById(personId);
+
+  // get the degree information
+  const degreeInformation = await getDegreesForPerson(personId);
+
+  // get the address information
+  const addressInformation = await getAddressesForPerson(personId);
+
+  // get the contact information
+  const contactInformation = await getContactsForPerson(personId);
+
+  // get the involvement information (none for now)
+  const involvmentInformation = [];
+
+  // return all of the data
+  return {
+    personalInformation,
+    degreeInformation,
+    addressInformation,
+    contactInformation,
+    involvmentInformation,
+  };
+}
+
+/*
+Helper function to update the degree information for a person.
+*/
+async function updateDegreesForPerson(personId, degrees) {
+  // Get the person's current degrees
+  const currentDegreeIds = await getDegreeIdsForPerson(personId);
+  let updatedDegreeIds = [];
+
+  // Add/update the given degrees
+  for (const degree of degrees) {
+    const peopleDegreeId = degree.peopleDegreeId || null;
+
+    // degree does not previously have a peopleDegreeId -> this means its new (add degree)
+    if (!peopleDegreeId) {
+      const addedDegree = await addDegree(degree, personId);
+      console.log("Added new degree: ", addedDegree);
+    } else {
+      // previous peopleDegreeId exists, update the degree
+      const updatedDegree = await updateDegree(
+        peopleDegreeId,
+        personId,
+        degree
+      );
+      console.log("Updated degree: ", updatedDegree);
+      if (updatedDegree == true) {
+        updatedDegreeIds.push(peopleDegreeId);
+      }
+    }
+  }
+
+  // Delete degrees not included in the update
+  for (const degreeId of currentDegreeIds) {
+    if (!updatedDegreeIds.includes(degreeId)) {
+      await deleteDegreeById(degreeId);
+      console.log("Deleted degree: ", degreeId);
+    }
+  }
+}
+
+/*
+Helper function to update addresses for a person.
+*/
+async function updateAddressesForPerson(personId, addresses) {
+  // Get the current addresses
+  const currentAddresses = await getAddressesForPerson(personId);
+  let updatedAddressIds = [];
+
+  for (const address of addresses) {
+    const addressId = address.addressId || null;
+
+    if (!addressId) {
+      const addedAddress = await addAddress(address, personId);
+      console.log("Added new address: ", addedAddress);
+    } else {
+      const updatedAddress = await updateAddress(addressId, personId, address);
+      if (updatedAddress != null) {
+        console.log("Updated address: ", updatedAddress);
+        updatedAddressIds.push(addressId);
+      } else {
+        console.log("Error updating adddress");
+      }
+    }
+  }
+
+  // Delete addresses not included in the update
+  for (const currentAddress of currentAddresses) {
+    if (!updatedAddressIds.includes(currentAddress.addressId)) {
+      await deleteAddressById(currentAddress.addressId);
+      console.log("Deleted address: ", currentAddress.addressId);
+    }
+  }
+}
+
+/*
+Helper function to update contacts for a person.
+*/
+async function updateContactsForPerson(personId, contacts) {
+  // Get the current contacts
+  const currentContacts = await getContactsForPerson(personId);
+  let updatedContactIds = [];
+
+  for (const contact of contacts) {
+    const contactId = contact.peopleContactId || null;
+
+    if (!contactId) {
+      const addedContact = await addContact(contact, personId);
+      console.log("Added new contact: ", addedContact);
+    } else {
+      const updatedContact = await updateContact(contactId, personId, contact);
+      console.log("Updated contact: ", updatedContact);
+      if (updatedContact == true) {
+        updatedContactIds.push(contactId);
+      }
+    }
+  }
+
+  // Delete contacts not included in the update
+  for (const currentContact of currentContacts) {
+    if (!updatedContactIds.includes(currentContact.peopleContactId)) {
+      // TODO: delete contact by id
+      let success = await deleteContactById(currentContact.peopleContactId);
+      if (success == true) {
+        console.log("Deleted contact: ", currentContact.peopleContactId);
+      } else {
+        console.log("Error deleting contact: ", currentContact.peopleContactId);
+      }
+    }
+  }
+}
+
+async function updateInvolvementsForPerson(personId, involevements) {}
+
+module.exports = {
+  createPerson,
+  findByName,
+  deleteById,
+  updatePersonById,
+  getPersonFullDetails,
+};