From 929f609f2436988a64baeacbf3f5dc6cb0594d6f Mon Sep 17 00:00:00 2001 From: Joel Thomas Date: Fri, 12 Jun 2026 03:19:43 +0530 Subject: [PATCH 1/3] Implement Model Refactoring 1959: Model Refactoring UserStory #1959 1. Replaced CSV-based User serialization and deserialization with SerializedUser record-based serialization for shared memory storage. 2. Implemented User::serialize() to convert User objects into fixed-size SerializedUser structures containing user details and enum values. 3. Implemented User::deserialize() to reconstruct User objects directly from SerializedUser records. 4. Updated User class interfaces to use SerializedUser types instead of std::string serialization APIs. 5. Removed legacy CSV serialization support, including CSV parsing logic and header generation functionality. 6. Added SerializedUser dependencies through SerializedRecords.h inclusion and forward declaration support. N/A Sreeja Reghukumar, please review --- .../models/User.cpp | 82 +++++++------------ .../models/User.h | 6 +- 2 files changed, 33 insertions(+), 55 deletions(-) diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.cpp index 0b4e86e..c4dc928 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.cpp @@ -8,6 +8,7 @@ Date: 19-May-2026 */ #include +#include "SerializedRecords.h" #include "User.h" #include "Notification.h" #include "Enums.h" @@ -28,7 +29,8 @@ Returns: User::User() : m_id("USR" + std::to_string(++m_uid)), m_type(util::UserType::CUSTOMER), - m_status(util::State::ACTIVE) {} + m_status(util::State::ACTIVE) { +} /* Function: User @@ -51,7 +53,8 @@ User::User(const std::string& userName, const std::string& password, const std:: m_phone(phone), m_email(email), m_type(role), - m_status(util::State::ACTIVE) {} + m_status(util::State::ACTIVE) { +} /* Function: User (parameterized constructor with ID) @@ -324,68 +327,43 @@ void User::setState(util::State status) /* Function: serialize -Description: Serializes the user into a CSV-formatted string. +Description: Serializes the User object into a SerializedUser record. Parameters: - None Returns: - - std::string: Serialized user record + - SerializedUser: Serialized representation of the user */ -std::string User::serialize() const +SerializedUser User::serialize() const { - std::ostringstream serializedUser; - serializedUser << m_id << ',' - << m_userName << ',' - << m_password << ',' - << m_name << ',' - << m_phone << ',' - << m_email << ',' - << util::getUserTypeString(m_type) << ',' - << util::getStateString(m_status); - return serializedUser.str(); + SerializedUser serialized = {}; + strcpy_s(serialized.id, sizeof(serialized.id), m_id.c_str()); + strcpy_s(serialized.username, sizeof(serialized.username), m_userName.c_str()); + strcpy_s(serialized.password, sizeof(serialized.password), m_password.c_str()); + strcpy_s(serialized.name, sizeof(serialized.name), m_name.c_str()); + strcpy_s(serialized.phone, sizeof(serialized.phone), m_phone.c_str()); + strcpy_s(serialized.email, sizeof(serialized.email), m_email.c_str()); + serialized.userType = m_type; + serialized.status = m_status; + return serialized; } /* Function: deserialize -Description: Deserializes a CSV-formatted string into a User object. +Description: Deserializes a SerializedUser record into a User object. Parameters: - - record: const std::string&, serialized user record + - serializedUser: const SerializedUser&, serialized user record Returns: - User*: Pointer to the deserialized User object */ -User* User::deserialize(const std::string& record) +User* User::deserialize(const SerializedUser& serializedUser) { - std::string id, name, username, phone, password, email; - std::string userTypeString, stateString; - std::istringstream serializedUser(record); - getline(serializedUser, id, ','); - getline(serializedUser, username, ','); - getline(serializedUser, password, ','); - getline(serializedUser, name, ','); - getline(serializedUser, phone, ','); - getline(serializedUser, email, ','); - getline(serializedUser, userTypeString, ','); - getline(serializedUser, stateString); - util::UserType userType = util::getUserType(userTypeString); - util::State status = util::getState(stateString); - return Factory::getObject(id, - username, - password, - name, - phone, - email, - userType, - status); -} - -/* -Function: getHeaders -Description: Retrieves the CSV headers for user serialization. -Parameters: - - None -Returns: - - std::string: Header string ("ID,Username,Password,Name,Phone,Email,UserType,UserStatus") -*/ -std::string User::getHeaders() -{ - return "ID,Username,Password,Name,Phone,Email,UserType,UserStatus"; + return Factory::getObject( + serializedUser.id, + serializedUser.username, + serializedUser.password, + serializedUser.name, + serializedUser.phone, + serializedUser.email, + serializedUser.userType, + serializedUser.status); } \ No newline at end of file diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.h index 12923f6..1026bd3 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.h @@ -14,6 +14,7 @@ Date: 19-May-2026 #include "Enums.h" class Notification; +struct SerializedUser; class User : public Observer { @@ -51,7 +52,6 @@ public: void addNotification(Notification* notification) override; void setRole(util::UserType role); void setState(util::State status); - std::string serialize() const; - static User* deserialize(const std::string&); - static std::string getHeaders(); + SerializedUser serialize() const; + static User* deserialize(const SerializedUser& serializedUser); }; From 89fc66218116d8d9a72aac641ead194724835956 Mon Sep 17 00:00:00 2001 From: Joel Thomas Date: Fri, 12 Jun 2026 11:31:03 +0530 Subject: [PATCH 2/3] Implement Service Refactoring 1960: Service Refactoring UserStory #1960 1. Replaced the Controller load/save workflow with initialize() and shutdown() methods. 2. Moved startup checks such as admin verification, low stock alerts, and payment reminders into Controller::initialize(). 3. Updated UserInterface to use the new Controller initialization and shutdown flow. 4. Updated DataStore::getUsers() and DataStore::getNotifications() to load data directly from shared memory. 5. Added logic to rebuild user notification mappings when user data is loaded from shared memory. 6. Implemented user and notification persistence through DataStore::saveUsers() and DataStore::saveNotifications(). 7. Updated UserManagementService to use TrackedRecord-based shared memory records. 8. Added DataStore locking and unlocking to user management operations for synchronization. 9. Updated createUser(), updateUserDetails(), removeUser(), and deleteNotification() to persist changes through shared memory. 10. Removed legacy loadUsers() and saveUsers() implementations from UserManagementService. 11. Added required header dependencies for shared memory support. N/A Sreeja Reghukumar, please review --- .../Trenser.VehicleServiceSystem.vcxproj | 1 + .../controllers/Controller.cpp | 72 +++---- .../controllers/Controller.h | 5 +- .../datastores/DataStore.cpp | 21 +++ .../datastores/DataStoreLockGuard.h | 28 +++ .../datastores/sharedmemory/SharedMemory.cpp | 1 + .../services/UserManagementService.cpp | 177 ++++++++---------- .../services/UserManagementService.h | 2 - .../views/UserInterface.cpp | 9 +- 9 files changed, 163 insertions(+), 153 deletions(-) create mode 100644 Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStoreLockGuard.h diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj index 6a269f5..7c4bfd3 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj @@ -157,6 +157,7 @@ + diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp index 9bc1d86..487ecd5 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp @@ -588,63 +588,37 @@ void Controller::configureNotifications(bool paymentNotifications, bool serviceN } /* -Function: loadSystemData -Description: Loads all system data from persistent storage into memory. - Invokes the respective management services to load users, inventory items, services, - combo packages, service bookings, job cards, invoices, and observers. +Function: initialize +Description: Initializes the system and run system checks to ensure critical configurations, such as verifying admin existence. Parameters: - None Returns: - - void + - bool */ -void Controller::loadSystemData() +bool Controller::initialize() { - m_userManagementService.loadUsers(); - m_inventoryManagementService.loadInventoryItems(); - m_serviceManagementService.loadServices(); - m_serviceManagementService.loadComboPackages(); - m_serviceManagementService.loadServiceBookings(); - m_serviceManagementService.loadJobCards(); - m_paymentManagementService.loadInvoices(); - m_serviceManagementService.loadObservers(); - m_paymentManagementService.loadObservers(); - m_inventoryManagementService.loadObservers(); -} + auto& dataStore = DataStore::getInstance(); -/* -Function: saveSystemData -Description: Saves all system data from memory back to persistent storage. - Invokes the respective management services to save users, inventory items, services, - combo packages, service bookings, job cards, invoices, and observers. -Parameters: - - None -Returns: - - void -*/ -void Controller::saveSystemData() -{ - m_userManagementService.saveUsers(); - m_inventoryManagementService.saveInventoryItems(); - m_serviceManagementService.saveServices(); - m_serviceManagementService.saveComboPackages(); - m_serviceManagementService.saveServiceBookings(); - m_serviceManagementService.saveJobCards(); - m_paymentManagementService.saveInvoices(); - m_serviceManagementService.saveObservers(); - m_paymentManagementService.saveObservers(); - m_inventoryManagementService.saveObservers(); -} - -/* -Function: runSystemChecks -Description: Runs system checks to ensure critical configurations, such as verifying admin existence. -Parameter: None -Return type: void -*/ -void Controller::runSystemChecks() -{ + if (!dataStore.initialize()) + { + return false; + } m_userManagementService.ensureAdminExists(); m_inventoryManagementService.sendLowStockAlerts(); m_paymentManagementService.sendPaymentReminders(); + return true; } +/* +Function: shutdown +Description: Shutdown the system, and do necessary cleanups +Parameters: + - None +Returns: + - void +*/ +void Controller::shutdown() +{ + auto& dataStore = DataStore::getInstance(); + dataStore.shutdown(); +} diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h index 35241a0..7ec1c30 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.h @@ -70,7 +70,6 @@ public: util::Vector getNotifications(); void deleteNotification(const std::string& notificationID); void configureNotifications(bool paymentNotifications, bool serviceNotifications); - void loadSystemData(); - void saveSystemData(); - void runSystemChecks(); + bool initialize(); + void shutdown(); }; \ No newline at end of file diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.cpp index 1cade32..bda9ac0 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.cpp @@ -228,6 +228,22 @@ Returns: */ util::Map>& DataStore::getUsers() { + auto users = loadRecords(m_users); + refreshCache(m_userCache, users); + auto& notifications = getNotifications(); + int numberOfNotifications = m_notificationCache.getSize(); + for (int index = 0; index < numberOfNotifications; index++) + { + Notification* notification = notifications.getValueAt(index).data; + const std::string& recipientUserId = notification->getRecipientUserId(); + int userIndex = m_userCache.find(recipientUserId); + if (userIndex == -1) + { + throw std::runtime_error("Invalid recipient user ID"); + } + User* user = m_userCache.getValueAt(userIndex).data; + user->addNotification(notification); + } return m_userCache; } @@ -241,6 +257,8 @@ Returns: */ util::Map>& DataStore::getNotifications() { + auto notifications = loadRecords(m_notifications); + refreshCache(m_notificationCache, notifications); return m_notificationCache; } @@ -371,6 +389,8 @@ Returns: */ void DataStore::saveUsers() { + saveRecords(m_users, m_userCache); + saveNotifications(); } /* @@ -383,6 +403,7 @@ Returns: */ void DataStore::saveNotifications() { + saveRecords(m_notifications, m_notificationCache); } /* diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStoreLockGuard.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStoreLockGuard.h new file mode 100644 index 0000000..2e04eb0 --- /dev/null +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStoreLockGuard.h @@ -0,0 +1,28 @@ +/* +File: DataStoreLockGuard.h +Description: Defines the DataStoreLockGuard class used to manage DataStore + locking and unlocking automatically within a scope. +Author: Trenser +Date: 12-June-2026 +*/ + +#pragma once +#include "DataStore.h" + +class DataStoreLockGuard +{ +public: + explicit DataStoreLockGuard(DataStore& dataStore) + : m_dataStore(dataStore) + { + m_dataStore.lockDataStore(); + } + ~DataStoreLockGuard() + { + m_dataStore.unlockDataStore(); + } + DataStoreLockGuard(const DataStoreLockGuard&) = delete; + DataStoreLockGuard& operator=(const DataStoreLockGuard&) = delete; +private: + DataStore& m_dataStore; +}; \ No newline at end of file diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/SharedMemory.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/SharedMemory.cpp index 6a10c9f..4b151e3 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/SharedMemory.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/SharedMemory.cpp @@ -10,6 +10,7 @@ Created: 11-June-2026 */ #include "SharedMemory.h" +#include "Windows.h" #include "Config.h" /* diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp index 8ba68d0..3eeead8 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp @@ -20,6 +20,9 @@ Date:19-May-2026 #include "UserManagementService.h" #include "Vector.h" #include "Validator.h" +#include "Utility.h" +#include "TrackedRecord.h" +#include "DataStoreLockGuard.h" /* Function: ensureAdminExists @@ -31,12 +34,13 @@ Return type: void */ void UserManagementService::ensureAdminExists() { + DataStoreLockGuard lock(m_dataStore); auto& usersMap = m_dataStore.getUsers(); int usersMapSize = usersMap.getSize(); bool isAdminFound = false; for (int index = 0; index < usersMapSize; index++) { - User* user = usersMap.getValueAt(index); + User* user = usersMap.getValueAt(index).data; if (user && user->getUserType() == util::UserType::ADMIN) { isAdminFound = true; @@ -73,7 +77,9 @@ void UserManagementService::createUser(const std::string& username, const std::s InventoryManagementService inventoryManagementService; PaymentManagementService paymentManagementService; ServiceManagementService serviceManagementService; - auto& usersMap = m_dataStore.getUsers(); + DataStoreLockGuard lock(m_dataStore); + auto& trackedUsersMap = m_dataStore.getUsers(); + auto usersMap = util::getObjects(trackedUsersMap); if (util::isUsernameDuplicate(username, usersMap)) { throw std::runtime_error("Username already exists"); @@ -87,13 +93,14 @@ void UserManagementService::createUser(const std::string& username, const std::s throw std::runtime_error("Phone already exists"); } User* newUser = Factory::getObject(username, password, name, phone, email, type); - usersMap.insert(newUser->getId(), newUser); + trackedUsersMap.insert(newUser->getId(), util::createNewRecord(newUser)); paymentManagementService.attach(newUser); serviceManagementService.attach(newUser); if (newUser->getUserType() == util::UserType::ADMIN) { inventoryManagementService.attach(newUser); } + m_dataStore.saveUsers(); } /* @@ -107,19 +114,24 @@ Return type: void */ void UserManagementService::updateUserDetails(const std::string& userID, const std::string& email, const std::string& phone) { - auto& usersMap = m_dataStore.getUsers(); - int index = usersMap.find(userID); + DataStoreLockGuard lock(m_dataStore); + auto& trackedUsersMap = m_dataStore.getUsers(); + auto usersMap = util::getObjects(trackedUsersMap); + int index = trackedUsersMap.find(userID); if (index == -1) { throw std::runtime_error("User does not exist!\n"); } - User* user = usersMap.getValueAt(index); + User* user = trackedUsersMap.getValueAt(index).data; + bool isModified = false; if (email != user->getEmail()) { if (util::isEmailDuplicate(email, usersMap)) { throw std::runtime_error("Email already exists!\n"); } + user->setEmail(email); + isModified = true; } if (phone != user->getPhone()) { @@ -127,9 +139,14 @@ void UserManagementService::updateUserDetails(const std::string& userID, const s { throw std::runtime_error("Phone number already exists!\n"); } + user->setPhone(phone); + isModified = true; + } + if (isModified) + { + trackedUsersMap.getValueAt(index).state = RecordState::MODIFIED; + m_dataStore.saveUsers(); } - user->setEmail(email); - user->setPhone(phone); } /* @@ -144,12 +161,13 @@ Throws: */ util::Vector UserManagementService::getUserNotifications(const std::string& userID) { - auto& usersMap = m_dataStore.getUsers(); - if (usersMap.find(userID) == -1) + DataStoreLockGuard lock(m_dataStore); + auto& trackedUsersMap = m_dataStore.getUsers(); + if (trackedUsersMap.find(userID) == -1) { throw std::runtime_error("No user found with given UserID"); } - User* user = usersMap[userID]; + User* user = trackedUsersMap[userID].data; if (user) { auto& notifications = user->getNotifications(); @@ -159,6 +177,7 @@ util::Vector UserManagementService::getUserNotifications(const st { notificationsVector.push_back(notifications.getValueAt(index)); } + m_dataStore.unlockDataStore(); return notificationsVector; } else @@ -169,97 +188,41 @@ util::Vector UserManagementService::getUserNotifications(const st /* Function: deleteNotification -Description: Deletes a specific notification associated with a given user ID. +Description: Marks a specific notification associated with a given user + as inactive. Parameters: - notificationID: The unique ID of the notification to be deleted. - userID: The unique ID of the user whose notification is to be deleted. Returns: - void Throws: - - std::runtime_error if no user is found with the given UserID or if no notification is found with the given NotificationID. + - std::runtime_error if no user is found with the given UserID or + if no notification is found with the given NotificationID. */ void UserManagementService::deleteNotification(const std::string& notificationID, const std::string& userID) { - auto& usersMap = m_dataStore.getUsers(); - if (usersMap.find(userID) == -1) + DataStoreLockGuard lock(m_dataStore); + auto& trackedUsersMap = m_dataStore.getUsers(); + auto& trackedNotificationsMap = m_dataStore.getNotifications(); + int userIndex = trackedUsersMap.find(userID); + if (userIndex == -1) { throw std::runtime_error("No user found with given UserID"); } - User* user = usersMap[userID]; + User* user = trackedUsersMap.getValueAt(userIndex).data; auto& notifications = user->getNotifications(); if (notifications.find(notificationID) == -1) { throw std::runtime_error("No notification found with given NotificationID"); } - notifications.remove(notificationID); -} - -/* -Function: loadUsers -Description: Loads users and notifications from persistent storage into the datastore. - Validates that each notification’s recipient exists and attaches the - notification to the corresponding user. -Parameters: - - None -Returns: - - void -Throws: - - std::runtime_error if a notification recipient user ID is invalid -*/ -void UserManagementService::loadUsers() -{ - util::FileManager userFileManager(config::file::USER_FILE); - util::FileManager notificationFileManager(config::file::NOTIFICATION_FILE); - auto& users = m_dataStore.getUsers(); - auto usersMap = userFileManager.load(); - auto notificationsMap = notificationFileManager.load(); - int numberOfUsers = usersMap.getSize(); - int numberOfNotifications = notificationsMap.getSize(); - for (int index = 0; index < numberOfUsers; index++) - { - users[usersMap.getKeyAt(index)] = usersMap.getValueAt(index); - } - for (int index = 0; index < numberOfNotifications; index++) - { - Notification* notification = notificationsMap.getValueAt(index); - const std::string& recipientUserId = notification->getRecipientUserId(); - int userIndex = users.find(recipientUserId); - if (userIndex == -1) - { - throw std::runtime_error("Invalid recipient user ID"); - } - User* user = users.getValueAt(userIndex); - user->addNotification(notification); - } -} - -/* -Function: saveUsers -Description: Saves users and their notifications from the datastore to persistent storage. - Collects notifications from all users into a single map before saving. -Parameters: - - None -Returns: - - void -*/ -void UserManagementService::saveUsers() -{ - util::FileManager userFileManager(config::file::USER_FILE); - util::FileManager notificationFileManager(config::file::NOTIFICATION_FILE); - auto& users = m_dataStore.getUsers(); - util::Map notifications; - for (int userIndex = 0; userIndex < users.getSize(); userIndex++) - { - User* user = users.getValueAt(userIndex); - auto& userNotifications = user->getNotifications(); - for (int notificationIndex = 0; notificationIndex < userNotifications.getSize(); notificationIndex++) - { - notifications[userNotifications.getKeyAt(notificationIndex)] = - userNotifications.getValueAt(notificationIndex); - } - } - userFileManager.save(users); - notificationFileManager.save(notifications); + int notificationIndex = trackedNotificationsMap.find(notificationID); + if (notificationIndex == -1) + { + throw std::runtime_error("No notification found with given NotificationID"); + } + notifications[notificationID]->setState(util::State::INACTIVE); + trackedNotificationsMap.getValueAt(notificationIndex).state = RecordState::MODIFIED; + m_dataStore.saveNotifications(); } /* @@ -270,7 +233,9 @@ Return type: util::Map */ util::Map UserManagementService::getUsers() { - return m_dataStore.getUsers(); + DataStoreLockGuard lock(m_dataStore); + auto users = util::getObjects(m_dataStore.getUsers()); + return users; } /* @@ -281,10 +246,12 @@ Return type: User* */ User* UserManagementService::getUser(const std::string& userID) { - int index = m_dataStore.getUsers().find(userID); + DataStoreLockGuard lock(m_dataStore); + auto& trackedUsersMap = m_dataStore.getUsers(); + int index = trackedUsersMap.find(userID); if (index != -1) { - return m_dataStore.getUsers().getValueAt(index); + return trackedUsersMap.getValueAt(index).data; } return nullptr; } @@ -300,35 +267,53 @@ void UserManagementService::removeUser(const std::string& userID) InventoryManagementService inventoryManagementService; PaymentManagementService paymentManagementService; ServiceManagementService serviceManagementService; - int index = m_dataStore.getUsers().find(userID); + DataStoreLockGuard lock(m_dataStore); + auto& trackedUsersMap = m_dataStore.getUsers(); + int index = trackedUsersMap.find(userID); if (index != -1) { - User* user = m_dataStore.getUsers().getValueAt(index); + User* user = trackedUsersMap.getValueAt(index).data; if (user != nullptr) { if (user->getUserType() == util::UserType::CUSTOMER) { - serviceManagementService.cancelCustomerServiceBookings(userID); + serviceManagementService.cancelCustomerServiceBookings(userID); } if (user->getUserType() == util::UserType::TECHNICIAN) { serviceManagementService.cancelTechnicianJobs(userID); } - user->setState(util::State::INACTIVE); inventoryManagementService.detach(user); paymentManagementService.detach(user); serviceManagementService.detach(user); + user->setState(util::State::INACTIVE); + trackedUsersMap.getValueAt(index).state = RecordState::MODIFIED; + m_dataStore.saveUsers(); } } } -util::Map UserManagementService::getUsers(util::UserType type) +/* +Function: getUsers +Description: Retrieves all active users of the specified type from + the DataStore. +Parameters: + - type: The user type to filter by + (ADMIN, CUSTOMER, or TECHNICIAN). +Returns: + - util::Map: + Collection of active users matching the specified type, + keyed by user ID. +*/ +util::Map UserManagementService::getUsers(util::UserType type) { - util::Map& currentUsers = m_dataStore.getUsers(); + DataStoreLockGuard lock(m_dataStore); + auto& trackedUsersMap = m_dataStore.getUsers(); + util::Map currentUsers = util::getObjects(trackedUsersMap); util::Map filteredUsersMap; - for (int iterator = 0; iterator < currentUsers.getSize(); iterator++) + for (int index = 0; index < currentUsers.getSize(); index++) { - User* currentUser = currentUsers.getValueAt(iterator); + User* currentUser = currentUsers.getValueAt(index); if (currentUser && currentUser->getState() == util::State::ACTIVE && currentUser->getUserType() == type) { filteredUsersMap.insert(currentUser->getId(), currentUser); diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.h index b448872..28aa446 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.h @@ -31,6 +31,4 @@ public: util::Vector getUserNotifications(const std::string& userID); void deleteNotification(const std::string& notificationID, const std::string& userID); void ensureAdminExists(); - void loadUsers(); - void saveUsers(); }; diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/UserInterface.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/UserInterface.cpp index 4596d9b..926fc9e 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/UserInterface.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/UserInterface.cpp @@ -27,8 +27,11 @@ void UserInterface::run() { try { - m_controller.loadSystemData(); - m_controller.runSystemChecks(); + if (!m_controller.initialize()) + { + std::cout << "Error: Failed to initialize the system!"; + return; + } bool isMenuActive = true; while (isMenuActive) { @@ -49,7 +52,7 @@ void UserInterface::run() util::pressEnter(); } } - m_controller.saveSystemData(); + m_controller.shutdown(); } catch (const std::invalid_argument& exception) { From b5c8b1ee9bdc97071c4d92cefc68e852c881c20f Mon Sep 17 00:00:00 2001 From: Joel Thomas Date: Mon, 15 Jun 2026 14:46:37 +0530 Subject: [PATCH 3/3] Implement review fixes --- .../services/UserManagementService.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp index 3eeead8..9b1c61c 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp @@ -177,7 +177,6 @@ util::Vector UserManagementService::getUserNotifications(const st { notificationsVector.push_back(notifications.getValueAt(index)); } - m_dataStore.unlockDataStore(); return notificationsVector; } else