From 67ac7f66258cd8cefeea0b3b81ab4f5d09974448 Mon Sep 17 00:00:00 2001 From: Joel Thomas Date: Fri, 12 Jun 2026 19:23:56 +0530 Subject: [PATCH] Implement Service Refactoring 1954: Implement Service Refactoring UserStory #1954 1. Refactored notification handling to persist notifications directly in the datastore instead of maintaining notification collections within User objects. 2. Removed recipient User pointer dependencies from Notification and retained recipient user identification through recipientUserId. 3. Implemented generic observer persistence support in DataStore with shared helper methods for loading and saving observer subscriptions. 4. Added datastore-backed observer management for ServiceManagementService, PaymentManagementService, and InventoryManagementService. 5. Updated attach() and detach() operations to load, modify, and persist observer subscriptions using shared memory mappings. 6. Refactored sendNotification() implementations to create and persist Notification records directly to the datastore for subscribed observers. 7. Updated UserManagementService notification retrieval and deletion logic to operate on datastore notification records filtered by recipient user ID. 8. Removed notification ownership and observer-specific notification APIs from User and Observer classes. 9. Added configurable shared memory growth factor support and updated mapping expansion logic to use centralized configuration values. 10. Removed obsolete NotificationManagementService implementation and updated project configuration references. 11. Added DataStoreLockGuard integration for observer and notification persistence operations to ensure synchronized datastore access. N/A Sreeja Reghukumar, please review --- .../Trenser.VehicleServiceSystem.vcxproj | 1 - ...enser.VehicleServiceSystem.vcxproj.filters | 6 +- .../core/patterns/Observer.h | 1 - .../datastores/DataStore.cpp | 89 +++++++++++++++---- .../datastores/DataStore.h | 2 + .../datastores/sharedmemory/SharedMemory.cpp | 2 +- .../models/Notification.cpp | 35 +------- .../models/Notification.h | 5 +- .../models/User.cpp | 44 --------- .../models/User.h | 5 +- .../services/InventoryManagementService.cpp | 50 ++++++----- .../NotificationManagementService.cpp | 1 - .../services/PaymentManagementService.cpp | 49 +++++----- .../services/ServiceManagementService.cpp | 77 +++++++--------- .../services/ServiceManagementService.h | 2 - .../services/UserManagementService.cpp | 26 +++--- .../utilities/Config.h | 1 + 17 files changed, 186 insertions(+), 210 deletions(-) delete mode 100644 Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/NotificationManagementService.cpp diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj index 7c4bfd3..b9a6f28 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj @@ -140,7 +140,6 @@ - diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters index 7e74b19..e9b5831 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters @@ -114,9 +114,6 @@ Source Files\DataStores - - Source Files\Services - Source Files\Core\Patterns @@ -278,5 +275,8 @@ Header Files\DataStores\SharedMemory + + Header Files + \ No newline at end of file diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/core/patterns/Observer.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/core/patterns/Observer.h index 7fd7262..e9eb955 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/core/patterns/Observer.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/core/patterns/Observer.h @@ -13,5 +13,4 @@ class Observer { public: virtual ~Observer() = default; - virtual void addNotification(Notification* notification) = 0; }; \ 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 bda9ac0..9f72555 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.cpp @@ -230,20 +230,6 @@ 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; } @@ -340,6 +326,37 @@ util::Map>& DataStore::getInvoices() return m_invoiceCache; } +/* +Function: getObservers +Description: Retrieves observer records from the specified observer mapping + and resolves them to User objects. +Parameters: + - mapping: Observer mapping to read from +Returns: + - util::Map: Collection of observer records +Throws: + - std::runtime_error if an observer references an invalid user ID +*/ +util::Map DataStore::getObservers(MappingInfo& mapping) +{ + auto& users = getUsers(); + util::Map observers; + SharedMemory::ensureLatestMapping(mapping); + size_t recordCount = SharedMemory::getRecordCount(mapping); + for (size_t index = 0; index < recordCount; index++) + { + const SerializedObserver* observer = static_cast(SharedMemory::getRecordAddress(mapping, index)); + int userIndex = users.find(observer->id); + if (userIndex == -1) + { + throw std::runtime_error("Invalid observer user ID"); + } + User* user = users.getValueAt(userIndex).data; + observers.insert(user->getId(), user); + } + return observers; +} + /* Function: getServiceManagementObservers Description: Retrieves all service management observer records from the datastore. @@ -350,7 +367,7 @@ Returns: */ util::Map DataStore::getServiceManagementObservers() { - return util::Map(); + return getObservers(m_serviceManagementObservers); } /* @@ -363,7 +380,7 @@ Returns: */ util::Map DataStore::getPaymentManagementObservers() { - return util::Map(); + return getObservers(m_paymentManagementObservers); } /* @@ -376,7 +393,7 @@ Returns: */ util::Map DataStore::getInventoryManagementObservers() { - return util::Map(); + return getObservers(m_inventoryManagementObservers); } /* @@ -390,7 +407,6 @@ Returns: void DataStore::saveUsers() { saveRecords(m_users, m_userCache); - saveNotifications(); } /* @@ -478,16 +494,49 @@ void DataStore::saveInvoices() { } +/* +Function: saveObservers +Description: Persists observer records to the specified observer mapping. +Parameters: + - mapping: MappingInfo&, observer mapping to save to + - observers: util::Map&, collection of observer records +Returns: + - None +*/ +void DataStore::saveObservers(MappingInfo& mapping, util::Map& observers) +{ + size_t observerCount = static_cast(observers.getSize()); + size_t capacity = config::file::INITIAL_CAPACITY; + while (capacity < observerCount) + { + capacity *= config::file::GROWTH_FACTOR; + } + if (!SharedMemory::resizeMapping(mapping, capacity)) + { + throw std::runtime_error("Failed to resize observer mapping"); + } + SharedMemory::setRecordCount(mapping, observerCount); + for (size_t index = 0; index < observerCount; index++) + { + SerializedObserver serializedObserver; + User* user = observers.getValueAt(static_cast(index)); + strcpy_s(serializedObserver.id, sizeof(serializedObserver.id), user->getId().c_str()); + SerializedObserver* destination = static_cast(SharedMemory::getRecordAddress(mapping, index)); + *destination = serializedObserver; + } +} + /* Function: saveServiceManagementObservers Description: Persists all service management observer records to the datastore. Parameters: - - observers: util::Map>&, collection of observer records + - observers: util::Map&, collection of observer records Returns: - None */ void DataStore::saveServiceManagementObservers(util::Map& observers) { + saveObservers(m_serviceManagementObservers, observers); } /* @@ -500,6 +549,7 @@ Returns: */ void DataStore::savePaymentManagementObservers(util::Map& observers) { + saveObservers(m_paymentManagementObservers, observers); } /* @@ -512,6 +562,7 @@ Returns: */ void DataStore::saveInventoryManagementObservers(util::Map& observers) { + saveObservers(m_inventoryManagementObservers, observers); } /* diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.h index 3950b11..62c585d 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.h @@ -86,6 +86,8 @@ private: void saveRecords(MappingInfo& mapping, util::Map>& records); template void clearCache(util::Map>&cache); template void refreshCache(util::Map>&cache, util::Map>&refreshedCache); + util::Map getObservers(MappingInfo& mapping); + void saveObservers(MappingInfo& mapping, util::Map& observers); }; /* diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/SharedMemory.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/SharedMemory.cpp index 4b151e3..0c5c7b1 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/SharedMemory.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/SharedMemory.cpp @@ -320,7 +320,7 @@ bool SharedMemory::ensureCapacityForInsert(MappingInfo& mapping) { return true; } - return resizeMapping(mapping, capacity * 2); + return resizeMapping(mapping, capacity * config::file::GROWTH_FACTOR); } /* diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Notification.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Notification.cpp index ad1b416..83532ec 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Notification.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Notification.cpp @@ -1,7 +1,7 @@ /* File: Notification.cpp Description: Implements the Notification class which represents system notifications in the Vehicle Service Management System. - Provides constructors, accessors, and mutators for notification details such as ID, recipient, title, message, and timestamp. + Provides constructors, accessors, and mutators for notification details such as ID, recipientID, title, message, and timestamp. Author: Trenser Date: 19-May-2026 */ @@ -23,9 +23,8 @@ Returns: - A new Notification object. */ Notification::Notification() - : m_id("NOT" + std::to_string(++m_uid)), - m_recipient(nullptr), m_state(util::State::ACTIVE) { -} + : m_id("NOT" + std::to_string(++m_uid)), + m_state(util::State::ACTIVE) {} /* Function: Notification @@ -39,10 +38,9 @@ Parameters: Returns: - A new Notification object. */ -Notification::Notification(const std::string& recipientUserId, User* recipient, const std::string& title, const std::string& message, const util::Timestamp& createdAt) +Notification::Notification(const std::string& recipientUserId, const std::string& title, const std::string& message, const util::Timestamp& createdAt) : m_id("NOT" + std::to_string(++m_uid)), m_recipientUserId(recipientUserId), - m_recipient(recipient), m_title(title), m_message(message), m_state(util::State::ACTIVE), @@ -65,7 +63,6 @@ Returns: Notification::Notification(const std::string& id, const std::string& recipientUserId, const std::string& title, const std::string& message, const util::Timestamp& createdAt, const util::State& state) : m_id(id), m_recipientUserId(recipientUserId), - m_recipient(nullptr), m_title(title), m_message(message), m_createdAt(createdAt), @@ -100,17 +97,6 @@ const std::string& Notification::getRecipientUserId() const return m_recipientUserId; } -/* -Function: getRecipient -Description: Retrieves the pointer to the recipient user. -Returns: - - User* representing the recipient. -*/ -User* Notification::getRecipient() const -{ - return m_recipient; -} - /* Function: getTitle Description: Retrieves the title of the notification. @@ -181,19 +167,6 @@ void Notification::setRecipientUserId(const std::string& recipientUserId) m_recipientUserId = recipientUserId; } -/* -Function: setRecipient -Description: Sets the recipient user pointer for the notification. -Parameters: - - recipient: Pointer to the User object. -Returns: - - void -*/ -void Notification::setRecipient(User* recipient) -{ - m_recipient = recipient; -} - /* Function: setTitle Description: Sets the title of the notification. diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Notification.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Notification.h index d92bc2c..a102cc6 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Notification.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/Notification.h @@ -20,24 +20,21 @@ private: static int m_uid; std::string m_id; std::string m_recipientUserId; - User* m_recipient; std::string m_title; std::string m_message; util::Timestamp m_createdAt; util::State m_state; public: Notification(); - Notification(const std::string& recipientUserId, User* recipient, const std::string& title, const std::string& message, const util::Timestamp& createdAt); + Notification(const std::string& recipientUserId, const std::string& title, const std::string& message, const util::Timestamp& createdAt); Notification(const std::string& id, const std::string& recipientUserId, const std::string& title, const std::string& message, const util::Timestamp& createdAt, const util::State& state); const std::string& getId() const; const std::string& getRecipientUserId() const; - User* getRecipient() const; const std::string& getTitle() const; const std::string& getMessage() const; const util::Timestamp& getCreatedAt() const; void setId(const std::string& id); void setRecipientUserId(const std::string& recipientUserId); - void setRecipient(User* recipient); void setTitle(const std::string& title); void setMessage(const std::string& message); void setCreatedAt(const util::Timestamp& createdAt); diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.cpp index c4dc928..5794259 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.cpp @@ -89,23 +89,6 @@ User::User(const std::string& userId, const std::string& userName, const std::st } } -/* -Function: ~User -Description: Destructor that cleans up dynamically allocated notifications associated with the user. -Parameters: - - None -Returns: - - void -*/ -User::~User() -{ - auto values = m_notifications.getValues(); - for (int index = 0; index < values.getSize(); index++) - { - delete values[index]; - } -} - /* Function: getId Description: Retrieves the unique ID of the user. @@ -172,17 +155,6 @@ const std::string& User::getEmail() const return m_email; } -/* -Function: getNotifications -Description: Retrieves the map of notifications associated with the user. -Returns: - - util::Map& representing the notifications. -*/ -util::Map& User::getNotifications() -{ - return m_notifications; -} - /* Function: getUserType Description: Retrieves the role of the user. @@ -283,22 +255,6 @@ void User::setEmail(const std::string& email) m_email = email; } -/* -Function: addNotification -Description: Adds a new notification to the user’s notification map. -Parameters: - - notification: Pointer to the Notification object. -Returns: - - void -*/ -void User::addNotification(Notification* notification) -{ - if (notification) - { - m_notifications.insert(notification->getId(), notification); - } -} - /* Function: setRole Description: Sets the role of the user. diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.h index 1026bd3..1a0f93f 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/models/User.h @@ -26,21 +26,19 @@ private: std::string m_name; std::string m_phone; std::string m_email; - util::Map m_notifications; util::UserType m_type; util::State m_status; public: User(); User(const std::string& userName, const std::string& password, const std::string& name, const std::string& phone, const std::string& email, util::UserType role); User(const std::string& userId, const std::string& userName, const std::string& password, const std::string& name, const std::string& phone, const std::string& email, util::UserType role, util::State status); - ~User(); + ~User() = default; const std::string& getId() const; const std::string& getUserName() const; const std::string& getPassword() const; const std::string& getName() const; const std::string& getPhone() const; const std::string& getEmail() const; - util::Map& getNotifications(); util::UserType getUserType() const; util::State getState() const; void setId(const std::string& id); @@ -49,7 +47,6 @@ public: void setName(const std::string& name); void setPhone(const std::string& phone); void setEmail(const std::string& email); - void addNotification(Notification* notification) override; void setRole(util::UserType role); void setState(util::State status); SerializedUser serialize() const; diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp index d08d957..aed6f3a 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/InventoryManagementService.cpp @@ -19,7 +19,7 @@ Date: 22-May-2026 #include "User.h" #include "Utility.h" #include "Vector.h" - +#include "DataStoreLockGuard.h" util::Map InventoryManagementService::m_observers{}; @@ -271,6 +271,9 @@ Returns: */ void InventoryManagementService::attach(User* user) { + DataStoreLockGuard lock(m_dataStore); + m_observers.clear(); + m_observers = m_dataStore.getInventoryManagementObservers(); if (user) { const std::string& userID = user->getId(); @@ -279,6 +282,7 @@ void InventoryManagementService::attach(User* user) m_observers[userID] = user; } } + m_dataStore.saveInventoryManagementObservers(m_observers); } /* @@ -291,6 +295,9 @@ Returns: */ void InventoryManagementService::detach(User* user) { + DataStoreLockGuard lock(m_dataStore); + m_observers.clear(); + m_observers = m_dataStore.getInventoryManagementObservers(); if (user) { const std::string& userID = user->getId(); @@ -299,6 +306,7 @@ void InventoryManagementService::detach(User* user) m_observers.remove(userID); } } + m_dataStore.saveInventoryManagementObservers(m_observers); } /* @@ -315,27 +323,27 @@ Throws: */ void InventoryManagementService::sendNotification(User* user, const std::string& title, const std::string& message) { - if (user) + if (!user) { - if (m_observers.find(user->getId()) != -1) - { - Notification* notification = - Factory::getObject( - user->getId(), - user, - title, - message, - util::Timestamp() - ); - if (notification) - { - user->addNotification(notification); - } - else - { - throw std::runtime_error("Failed to create notification"); - } - } + return; } + DataStoreLockGuard lock(m_dataStore); + m_observers = m_dataStore.getInventoryManagementObservers(); + if (m_observers.find(user->getId()) == -1) + { + return; + } + Notification* notification = Factory::getObject( + user->getId(), + title, + message, + util::Timestamp()); + if (!notification) + { + throw std::runtime_error("Failed to create notification"); + } + auto& trackedNotificationsMap = m_dataStore.getNotifications(); + trackedNotificationsMap.insert(notification->getId(), util::createNewRecord(notification)); + m_dataStore.saveNotifications(); } diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/NotificationManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/NotificationManagementService.cpp deleted file mode 100644 index cc23059..0000000 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/NotificationManagementService.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "NotificationManagementService.h" diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp index 1fc1ff8..1ebb273 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/PaymentManagementService.cpp @@ -21,6 +21,7 @@ Date: 20-May-2026 #include "Timestamp.h" #include "User.h" #include "Utility.h" +#include "DataStoreLockGuard.h" util::Map PaymentManagementService::m_observers{}; @@ -34,6 +35,9 @@ Returns: */ void PaymentManagementService::attach(User* user) { + DataStoreLockGuard lock(m_dataStore); + m_observers.clear(); + m_observers = m_dataStore.getPaymentManagementObservers(); if (user) { const std::string& userID = user->getId(); @@ -42,6 +46,7 @@ void PaymentManagementService::attach(User* user) m_observers[userID] = user; } } + m_dataStore.savePaymentManagementObservers(m_observers); } /* @@ -54,6 +59,9 @@ Returns: */ void PaymentManagementService::detach(User* user) { + DataStoreLockGuard lock(m_dataStore); + m_observers.clear(); + m_observers = m_dataStore.getPaymentManagementObservers(); if (user) { const std::string& userID = user->getId(); @@ -62,6 +70,7 @@ void PaymentManagementService::detach(User* user) m_observers.remove(userID); } } + m_dataStore.savePaymentManagementObservers(m_observers); } /* @@ -78,28 +87,28 @@ Throws: */ void PaymentManagementService::sendNotification(User* user, const std::string& title, const std::string& message) { - if (user) + if (!user) { - if (m_observers.find(user->getId()) != -1) - { - Notification* notification = - Factory::getObject( - user->getId(), - user, - title, - message, - util::Timestamp() - ); - if (notification) - { - user->addNotification(notification); - } - else - { - throw std::runtime_error("Failed to create notification"); - } - } + return; } + DataStoreLockGuard lock(m_dataStore); + m_observers = m_dataStore.getPaymentManagementObservers(); + if (m_observers.find(user->getId()) == -1) + { + return; + } + Notification* notification = Factory::getObject( + user->getId(), + title, + message, + util::Timestamp()); + if (!notification) + { + throw std::runtime_error("Failed to create notification"); + } + auto& trackedNotificationsMap = m_dataStore.getNotifications(); + trackedNotificationsMap.insert(notification->getId(), util::createNewRecord(notification)); + m_dataStore.saveNotifications(); } /* diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp index 1a9f753..102ba31 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.cpp @@ -26,6 +26,7 @@ Date:19-May-2026 #include "User.h" #include "UserManagementService.h" #include "Utility.h" +#include "DataStoreLockGuard.h" /* Function: purchaseService @@ -122,6 +123,9 @@ Returns: */ void ServiceManagementService::attach(User* user) { + DataStoreLockGuard lock(m_dataStore); + m_observers.clear(); + m_observers = m_dataStore.getServiceManagementObservers(); if (user) { const std::string& userID = user->getId(); @@ -130,6 +134,7 @@ void ServiceManagementService::attach(User* user) m_observers[userID] = user; } } + m_dataStore.saveServiceManagementObservers(m_observers); } /* @@ -142,6 +147,9 @@ Returns: */ void ServiceManagementService::detach(User* user) { + DataStoreLockGuard lock(m_dataStore); + m_observers.clear(); + m_observers = m_dataStore.getServiceManagementObservers(); if (user) { const std::string& userID = user->getId(); @@ -150,6 +158,7 @@ void ServiceManagementService::detach(User* user) m_observers.remove(userID); } } + m_dataStore.saveServiceManagementObservers(m_observers); } /* @@ -166,52 +175,28 @@ Throws: */ void ServiceManagementService::sendNotification(User* user, const std::string& title, const std::string& message) { - if (user) - { - if (m_observers.find(user->getId()) != -1) - { - Notification* notification = - Factory::getObject( - user->getId(), - user, - title, - message, - util::Timestamp() - ); - if (notification) - { - user->addNotification(notification); - } - else - { - throw std::runtime_error("Failed to create notification"); - } - } - } -} - -/* -Function: getObserverIDs -Description: Retrieves the IDs of all observers currently attached to the - ServiceManagementService. -Parameters: - - None -Returns: - - util::Vector: Vector of observer user IDs -*/ -util::Vector ServiceManagementService::getObserverIDs() -{ - util::Vector observerIDs; - int numberOfObservers = m_observers.getSize(); - for (int index = 0; index < numberOfObservers; index++) - { - User* observer = m_observers.getValueAt(index); - if (observer) - { - observerIDs.push_back(observer->getId()); - } - } - return observerIDs; + if (!user) + { + return; + } + DataStoreLockGuard lock(m_dataStore); + m_observers = m_dataStore.getServiceManagementObservers(); + if (m_observers.find(user->getId()) == -1) + { + return; + } + Notification* notification = Factory::getObject( + user->getId(), + title, + message, + util::Timestamp()); + if (!notification) + { + throw std::runtime_error("Failed to create notification"); + } + auto& trackedNotificationsMap = m_dataStore.getNotifications(); + trackedNotificationsMap.insert(notification->getId(), util::createNewRecord(notification)); + m_dataStore.saveNotifications(); } /* diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.h index b2a4384..f1ff966 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/ServiceManagementService.h @@ -53,6 +53,4 @@ public: void saveServiceBookings(); void loadJobCards(); void saveJobCards(); - void loadObservers(); - void saveObservers(); }; diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp index 9b1c61c..1be3a40 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.cpp @@ -170,12 +170,16 @@ util::Vector UserManagementService::getUserNotifications(const st User* user = trackedUsersMap[userID].data; if (user) { - auto& notifications = user->getNotifications(); - int numberOfNotifications = notifications.getSize(); + auto& trackedNotificationMap = m_dataStore.getNotifications(); + int numberOfNotifications = trackedNotificationMap.getSize(); util::Vector notificationsVector; for (int index = 0; index < numberOfNotifications; index++) { - notificationsVector.push_back(notifications.getValueAt(index)); + Notification* notification = trackedNotificationMap.getValueAt(index).data; + if (notification->getRecipientUserId() == userID && notification->getState() == util::State::ACTIVE) + { + notificationsVector.push_back(notification); + } } return notificationsVector; } @@ -208,20 +212,18 @@ void UserManagementService::deleteNotification(const std::string& notificationID { throw std::runtime_error("No user found with given 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"); - } 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(); + Notification* notification = trackedNotificationsMap.getValueAt(notificationIndex).data; + if (notification->getRecipientUserId() == userID) + { + notification->setState(util::State::INACTIVE); + trackedNotificationsMap.getValueAt(notificationIndex).state = RecordState::MODIFIED; + m_dataStore.saveNotifications(); + } } /* diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Config.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Config.h index 2eef19d..a2995b4 100644 --- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Config.h +++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Config.h @@ -29,6 +29,7 @@ namespace config namespace file { const size_t INITIAL_CAPACITY = 100; + const size_t GROWTH_FACTOR = 2; constexpr const char* DIRECTORY = "files/"; constexpr const char* INVENTORYITEM_FILE = "files/InventoryItem.dat"; constexpr const char* USER_FILE = "files/User.dat";