diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj
index 8627061..6a269f5 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj
@@ -102,7 +102,7 @@
true
_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
- $(ProjectDir)models;$(ProjectDir)controllers;$(ProjectDir)factories;$(ProjectDir)views;$(ProjectDir)services;$(ProjectDir)utilities;$(ProjectDir)core\patterns;$(ProjectDir)datastores;%(AdditionalIncludeDirectories)
+ $(ProjectDir)models;$(ProjectDir)controllers;$(ProjectDir)factories;$(ProjectDir)views;$(ProjectDir)services;$(ProjectDir)utilities;$(ProjectDir)core\patterns;$(ProjectDir)datastores;$(ProjectDir)datastores\sharedmemory;%(AdditionalIncludeDirectories)
Console
@@ -117,7 +117,7 @@
true
NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
- $(ProjectDir)models;$(ProjectDir)controllers;$(ProjectDir)factories;$(ProjectDir)views;$(ProjectDir)services;$(ProjectDir)utilities;$(ProjectDir)core\patterns;$(ProjectDir)datastores;%(AdditionalIncludeDirectories)
+ $(ProjectDir)models;$(ProjectDir)controllers;$(ProjectDir)factories;$(ProjectDir)views;$(ProjectDir)services;$(ProjectDir)utilities;$(ProjectDir)core\patterns;$(ProjectDir)datastores;$(ProjectDir)datastores\sharedmemory;%(AdditionalIncludeDirectories)
Console
@@ -129,6 +129,7 @@
+
@@ -156,6 +157,12 @@
+
+
+
+
+
+
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters
index 73b9291..7e74b19 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem.vcxproj.filters
@@ -64,6 +64,12 @@
{8057b93d-51a9-42df-b06e-01ce395f6308}
+
+ {ec639004-44c6-4bd6-9963-077adde82b5f}
+
+
+ {7aa8722e-adfa-466e-8211-de63f3b7892b}
+
@@ -141,6 +147,9 @@
Source Files\Models
+
+ Source Files\DataStores\SharedMemory
+
@@ -251,5 +260,23 @@
Header Files\Views
+
+ Header Files\DataStores\SharedMemory
+
+
+ Header Files\DataStores\SharedMemory
+
+
+ Header Files\DataStores\SharedMemory
+
+
+ Header Files\DataStores\SharedMemory
+
+
+ Header Files\DataStores\SharedMemory
+
+
+ Header Files\DataStores\SharedMemory
+
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp
index e3a85b0..9bc1d86 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/controllers/Controller.cpp
@@ -6,6 +6,7 @@ Description: Implementation file containing the method definitions of the
Author: Trenser
Date:19-May-2026
*/
+
#include "ComboPackage.h"
#include "Controller.h"
#include "Enums.h"
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.cpp
index 3419f44..1cade32 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.cpp
@@ -9,6 +9,200 @@ Date: 19-May-2026
*/
#include "DataStore.h"
+#include "Config.h"
+#include "SerializedRecords.h"
+#include "FileHelper.h"
+
+/*
+Function: DataStore
+Description: Constructs the DataStore singleton and initializes
+ internal handles to their default values.
+Parameters:
+ - None
+Returns:
+ - None
+*/
+DataStore::DataStore() :
+ m_globalMutex(NULL) {}
+
+/*
+Function: ~DataStore
+Description: Destroys the DataStore singleton and releases all
+ cached application objects owned by the datastore.
+ This includes users, notifications, services,
+ combo packages, inventory items, service bookings,
+ job cards, and invoices.
+Parameters:
+ - None
+Returns:
+ - None
+*/
+DataStore::~DataStore()
+{
+ clearCache(m_userCache);
+ clearCache(m_notificationCache);
+ clearCache(m_serviceCache);
+ clearCache(m_comboPackageCache);
+ clearCache(m_inventoryItemCache);
+ clearCache(m_serviceBookingCache);
+ clearCache(m_jobCardCache);
+ clearCache(m_invoiceCache);
+}
+
+/*
+Function: initialize
+Description: Initializes the shared-memory datastore.
+ Creates or opens the global datastore mutex,
+ configures all mapping metadata, and creates
+ or opens the file mappings used to persist
+ application data. After successful completion,
+ all datastore files are mapped into memory and
+ ready for use by the application.
+Parameter: None
+Return type: bool
+ - true : Initialization completed successfully.
+ - false : Failed to create the mutex or open
+ one or more file mappings.
+*/
+bool DataStore::initialize()
+{
+ m_globalMutex = CreateMutexA(NULL, FALSE, "VehicleServiceSystemMutex");
+ if (m_globalMutex == NULL)
+ {
+ return false;
+ }
+ if (!lockDataStore())
+ {
+ CloseHandle(m_globalMutex);
+ m_globalMutex = NULL;
+ return false;
+ }
+ bool success = true;
+ do
+ {
+ util::ensureDirectoryExists(config::file::DIRECTORY);
+ m_users.fileName = config::file::USER_FILE;
+ m_users.recordSize = sizeof(SerializedUser);
+ m_notifications.fileName = config::file::NOTIFICATION_FILE;
+ m_notifications.recordSize = sizeof(SerializedNotification);
+ m_services.fileName = config::file::SERVICE_FILE;
+ m_services.recordSize = sizeof(SerializedService);
+ m_comboPackages.fileName = config::file::COMBOPACKAGE_FILE;
+ m_comboPackages.recordSize = sizeof(SerializedComboPackage);
+ m_inventoryItems.fileName = config::file::INVENTORYITEM_FILE;
+ m_inventoryItems.recordSize = sizeof(SerializedInventoryItem);
+ m_serviceBookings.fileName = config::file::SERVICEBOOKING_FILE;
+ m_serviceBookings.recordSize = sizeof(SerializedServiceBooking);
+ m_jobCards.fileName = config::file::JOBCARD_FILE;
+ m_jobCards.recordSize = sizeof(SerializedJobCard);
+ m_invoices.fileName = config::file::INVOICE_FILE;
+ m_invoices.recordSize = sizeof(SerializedInvoice);
+ m_serviceManagementObservers.fileName = config::file::SERVICEMANAGEMENTOBSERVERS;
+ m_serviceManagementObservers.recordSize = sizeof(SerializedObserver);
+ m_paymentManagementObservers.fileName = config::file::PAYMENTMANAGEMENTOBSERVERS;
+ m_paymentManagementObservers.recordSize = sizeof(SerializedObserver);
+ m_inventoryManagementObservers.fileName = config::file::INVENTORYMANAGEMENTOBSERVERS;
+ m_inventoryManagementObservers.recordSize = sizeof(SerializedObserver);
+ if (!SharedMemory::createOrOpenMapping(m_users))
+ {
+ success = false;
+ break;
+ }
+ if (!SharedMemory::createOrOpenMapping(m_notifications))
+ {
+ success = false;
+ break;
+ }
+ if (!SharedMemory::createOrOpenMapping(m_services))
+ {
+ success = false;
+ break;
+ }
+
+ if (!SharedMemory::createOrOpenMapping(m_comboPackages))
+ {
+ success = false;
+ break;
+ }
+ if (!SharedMemory::createOrOpenMapping(m_inventoryItems))
+ {
+ success = false;
+ break;
+ }
+ if (!SharedMemory::createOrOpenMapping(m_serviceBookings))
+ {
+ success = false;
+ break;
+ }
+ if (!SharedMemory::createOrOpenMapping(m_jobCards))
+ {
+ success = false;
+ break;
+ }
+ if (!SharedMemory::createOrOpenMapping(m_invoices))
+ {
+ success = false;
+ break;
+ }
+ if (!SharedMemory::createOrOpenMapping(m_payments))
+ {
+ success = false;
+ break;
+ }
+ if (!SharedMemory::createOrOpenMapping(m_serviceManagementObservers))
+ {
+ success = false;
+ break;
+ }
+ if (!SharedMemory::createOrOpenMapping(m_paymentManagementObservers))
+ {
+ success = false;
+ break;
+ }
+ if (!SharedMemory::createOrOpenMapping(m_inventoryManagementObservers))
+ {
+ success = false;
+ break;
+ }
+ } while (false);
+ unlockDataStore();
+ if (!success)
+ {
+ shutdown();
+ }
+ return success;
+}
+
+/*
+Function: shutdown
+Description: Releases all shared-memory resources owned by the
+ datastore. Closes every file mapping, unmaps all
+ mapped views, and releases the datastore mutex.
+ After this call, the datastore must be initialized
+ again before use.
+Parameter: None
+Return type: void
+*/
+void DataStore::shutdown()
+{
+ SharedMemory::closeMapping(m_users);
+ SharedMemory::closeMapping(m_notifications);
+ SharedMemory::closeMapping(m_services);
+ SharedMemory::closeMapping(m_comboPackages);
+ SharedMemory::closeMapping(m_inventoryItems);
+ SharedMemory::closeMapping(m_serviceBookings);
+ SharedMemory::closeMapping(m_jobCards);
+ SharedMemory::closeMapping(m_invoices);
+ SharedMemory::closeMapping(m_payments);
+ SharedMemory::closeMapping(m_serviceManagementObservers);
+ SharedMemory::closeMapping(m_paymentManagementObservers);
+ SharedMemory::closeMapping(m_inventoryManagementObservers);
+ if (m_globalMutex != NULL)
+ {
+ CloseHandle(m_globalMutex);
+ m_globalMutex = NULL;
+ }
+}
/*
Function: getInstance
@@ -26,104 +220,346 @@ DataStore& DataStore::getInstance()
/*
Function: getUsers
-Description: Retrieves the internal map of users.
+Description: Retrieves all user records from the datastore.
Parameters:
- None
Returns:
- - Reference to util::Map containing all users.
+ - util::Map>: Collection of user records
*/
-util::Map& DataStore::getUsers()
+util::Map>& DataStore::getUsers()
{
- return m_users;
+ return m_userCache;
+}
+
+/*
+Function: getNotifications
+Description: Retrieves all notification records from the datastore.
+Parameters:
+ - None
+Returns:
+ - util::Map>: Collection of notification records
+*/
+util::Map>& DataStore::getNotifications()
+{
+ return m_notificationCache;
}
/*
Function: getServices
-Description: Retrieves the internal map of services.
+Description: Retrieves all service records from the datastore.
Parameters:
- None
Returns:
- - Reference to util::Map containing all services.
+ - util::Map>: Collection of service records
*/
-util::Map& DataStore::getServices()
+util::Map>& DataStore::getServices()
{
- return m_services;
+ return m_serviceCache;
}
/*
Function: getComboPackages
-Description: Retrieves the internal map of combo packages.
+Description: Retrieves all combo package records from the datastore.
Parameters:
- None
Returns:
- - Reference to util::Map containing all combo packages.
+ - util::Map>: Collection of combo package records
*/
-util::Map& DataStore::getComboPackages()
+util::Map>& DataStore::getComboPackages()
{
- return m_comboPackages;
-}
-
-/*
-Function: getServiceBookings
-Description: Retrieves the internal map of service bookings.
-Parameters:
- - None
-Returns:
- - Reference to util::Map containing all service bookings.
-*/
-util::Map& DataStore::getServiceBookings()
-{
- return m_serviceBookings;
-}
-
-/*
-Function: getJobCards
-Description: Retrieves the internal map of job cards.
-Parameters:
- - None
-Returns:
- - Reference to util::Map containing all job cards.
-*/
-util::Map& DataStore::getJobCards()
-{
- return m_jobCards;
+ return m_comboPackageCache;
}
/*
Function: getInventoryItems
-Description: Retrieves the internal map of inventory items.
+Description: Retrieves all inventory item records from the datastore.
Parameters:
- None
Returns:
- - Reference to util::Map containing all inventory items.
+ - util::Map>: Collection of inventory item records
*/
-util::Map& DataStore::getInventoryItems()
+util::Map>& DataStore::getInventoryItems()
{
- return m_inventoryItems;
+ return m_inventoryItemCache;
+}
+
+/*
+Function: getServiceBookings
+Description: Retrieves all service booking records from the datastore.
+Parameters:
+ - None
+Returns:
+ - util::Map>: Collection of service booking records
+*/
+util::Map>& DataStore::getServiceBookings()
+{
+ return m_serviceBookingCache;
+}
+
+/*
+Function: getJobCards
+Description: Retrieves all job card records from the datastore.
+Parameters:
+ - None
+Returns:
+ - util::Map>: Collection of job card records
+*/
+util::Map>& DataStore::getJobCards()
+{
+ return m_jobCardCache;
}
/*
Function: getInvoices
-Description: Retrieves the internal map of invoices.
+Description: Retrieves all invoice records from the datastore.
Parameters:
- None
Returns:
- - Reference to util::Map containing all invoices.
+ - util::Map>: Collection of invoice records
*/
-util::Map& DataStore::getInvoices()
+util::Map>& DataStore::getInvoices()
{
- return m_invoices;
+ return m_invoiceCache;
}
/*
-Function: getPayments
-Description: Retrieves the internal map of payments.
+Function: getServiceManagementObservers
+Description: Retrieves all service management observer records from the datastore.
Parameters:
- None
Returns:
- - Reference to util::Map containing all payments.
+ - util::Map: Collection of observer records
*/
-util::Map& DataStore::getPayments()
+util::Map DataStore::getServiceManagementObservers()
{
- return m_payments;
-}
\ No newline at end of file
+ return util::Map();
+}
+
+/*
+Function: getPaymentManagementObservers
+Description: Retrieves all payment management observer records from the datastore.
+Parameters:
+ - None
+Returns:
+ - util::Map: Collection of observer records
+*/
+util::Map DataStore::getPaymentManagementObservers()
+{
+ return util::Map();
+}
+
+/*
+Function: getInventoryManagementObservers
+Description: Retrieves all inventory management observer records from the datastore.
+Parameters:
+ - None
+Returns:
+ - util::Map: Collection of observer records
+*/
+util::Map DataStore::getInventoryManagementObservers()
+{
+ return util::Map();
+}
+
+/*
+Function: saveUsers
+Description: Persists all user records to the datastore.
+Parameters:
+ - None
+Returns:
+ - None
+*/
+void DataStore::saveUsers()
+{
+}
+
+/*
+Function: saveNotifications
+Description: Persists all notification records to the datastore.
+Parameters:
+ - None
+Returns:
+ - None
+*/
+void DataStore::saveNotifications()
+{
+}
+
+/*
+Function: saveServices
+Description: Persists all service records to the datastore.
+Parameters:
+ - None
+Returns:
+ - None
+*/
+void DataStore::saveServices()
+{
+}
+
+/*
+Function: saveComboPackages
+Description: Persists all combo package records to the datastore.
+Parameters:
+ - None
+Returns:
+ - None
+*/
+void DataStore::saveComboPackages()
+{
+}
+
+/*
+Function: saveInventoryItems
+Description: Persists all inventory item records to the datastore.
+Parameters:
+ - None
+Returns:
+ - None
+*/
+void DataStore::saveInventoryItems()
+{
+}
+
+/*
+Function: saveServiceBookings
+Description: Persists all service booking records to the datastore.
+Parameters:
+ - None
+Returns:
+ - None
+*/
+void DataStore::saveServiceBookings()
+{
+}
+
+/*
+Function: saveJobCards
+Description: Persists all job card records to the datastore.
+Parameters:
+ - None
+Returns:
+ - None
+*/
+void DataStore::saveJobCards()
+{
+}
+
+/*
+Function: saveInvoices
+Description: Persists all invoice records to the datastore.
+Parameters:
+ - None
+Returns:
+ - None
+*/
+void DataStore::saveInvoices()
+{
+}
+
+/*
+Function: saveServiceManagementObservers
+Description: Persists all service management observer records to the datastore.
+Parameters:
+ - observers: util::Map>&, collection of observer records
+Returns:
+ - None
+*/
+void DataStore::saveServiceManagementObservers(util::Map& observers)
+{
+}
+
+/*
+Function: savePaymentManagementObservers
+Description: Persists all payment management observer records to the datastore.
+Parameters:
+ - observers: util::Map&, collection of observer records
+Returns:
+ - None
+*/
+void DataStore::savePaymentManagementObservers(util::Map& observers)
+{
+}
+
+/*
+Function: saveInventoryManagementObservers
+Description: Persists all inventory management observer records to the datastore.
+Parameters:
+ - observers: util::Map&, collection of observer records
+Returns:
+ - None
+*/
+void DataStore::saveInventoryManagementObservers(util::Map& observers)
+{
+}
+
+/*
+Function: lockDataStore
+Description: Acquires exclusive access to the datastore.
+Parameters:
+ - None
+Returns:
+ - bool: True if the datastore was successfully locked, otherwise false
+*/
+bool DataStore::lockDataStore()
+{
+ return false;
+}
+
+/*
+Function: unlockDataStore
+Description: Releases exclusive access to the datastore.
+Parameters:
+ - None
+Returns:
+ - bool: True if the datastore was successfully unlocked, otherwise false
+*/
+bool DataStore::unlockDataStore()
+{
+ return false;
+}
+
+/*
+Function: lockDataStore
+Description: Acquires the datastore mutex, providing
+ exclusive access to the shared-memory
+ datastore. This function blocks until
+ the mutex becomes available or an error
+ occurs.
+Parameter: None
+Return type:
+ bool
+ - true : Mutex successfully acquired.
+ - false : Failed to acquire the mutex.
+*/
+bool DataStore::lockDataStore()
+{
+ if (m_globalMutex == NULL)
+ {
+ return false;
+ }
+ DWORD result = WaitForSingleObject(m_globalMutex, INFINITE);
+ return result == WAIT_OBJECT_0;
+}
+
+/*
+Function: unlockDataStore
+Description: Releases the datastore mutex after a
+ successful call to lockDataStore(),
+ allowing other processes to access the
+ shared-memory datastore.
+Parameter: None
+Return type:
+ bool
+ - true : Mutex successfully released.
+ - false : Failed to release the mutex.
+*/
+bool DataStore::unlockDataStore()
+{
+ if (m_globalMutex == NULL)
+ {
+ return false;
+ }
+ return ReleaseMutex(m_globalMutex) != 0;
+}
+
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.h
index cde9b4e..3950b11 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/DataStore.h
@@ -6,42 +6,232 @@ Date: 19-May-2026
*/
#pragma once
+#include
#include
#include "Map.h"
-
+#include "MappingInfo.h"
+#include "TrackedRecord.h"
+#include "SharedMemory.h"
class User;
+class Notification;
class Service;
class ComboPackage;
+class InventoryItem;
class ServiceBooking;
class JobCard;
-class InventoryItem;
class Invoice;
-class Payment;
class DataStore
{
private:
- util::Map m_users;
- util::Map m_services;
- util::Map m_comboPackages;
- util::Map m_serviceBookings;
- util::Map m_jobCards;
- util::Map m_inventoryItems;
- util::Map m_invoices;
- util::Map m_payments;
- DataStore() {}
-public:
- static DataStore& getInstance();
+ DataStore();
+ ~DataStore();
DataStore(const DataStore&) = delete;
DataStore& operator=(const DataStore&) = delete;
DataStore(DataStore&&) = delete;
DataStore& operator=(DataStore&&) = delete;
- util::Map& getUsers();
- util::Map& getServices();
- util::Map& getComboPackages();
- util::Map& getServiceBookings();
- util::Map& getJobCards();
- util::Map& getInventoryItems();
- util::Map& getInvoices();
- util::Map& getPayments();
-};
\ No newline at end of file
+ HANDLE m_globalMutex;
+ MappingInfo m_users;
+ MappingInfo m_notifications;
+ MappingInfo m_services;
+ MappingInfo m_comboPackages;
+ MappingInfo m_inventoryItems;
+ MappingInfo m_serviceBookings;
+ MappingInfo m_jobCards;
+ MappingInfo m_invoices;
+ MappingInfo m_payments;
+ MappingInfo m_serviceManagementObservers;
+ MappingInfo m_paymentManagementObservers;
+ MappingInfo m_inventoryManagementObservers;
+ util::Map> m_userCache;
+ util::Map> m_notificationCache;
+ util::Map> m_serviceCache;
+ util::Map> m_comboPackageCache;
+ util::Map> m_inventoryItemCache;
+ util::Map> m_serviceBookingCache;
+ util::Map> m_jobCardCache;
+ util::Map> m_invoiceCache;
+public:
+ static DataStore& getInstance();
+ bool initialize();
+ void shutdown();
+ util::Map>& getUsers();
+ util::Map>& getNotifications();
+ util::Map>& getServices();
+ util::Map>& getComboPackages();
+ util::Map>& getInventoryItems();
+ util::Map>& getServiceBookings();
+ util::Map>& getJobCards();
+ util::Map>& getInvoices();
+ util::Map getServiceManagementObservers();
+ util::Map getPaymentManagementObservers();
+ util::Map getInventoryManagementObservers();
+ void saveUsers();
+ void saveNotifications();
+ void saveServices();
+ void saveComboPackages();
+ void saveInventoryItems();
+ void saveServiceBookings();
+ void saveJobCards();
+ void saveInvoices();
+ void saveServiceManagementObservers(util::Map& observers);
+ void savePaymentManagementObservers(util::Map& observers);
+ void saveInventoryManagementObservers(util::Map& observers);
+ bool lockDataStore();
+ bool unlockDataStore();
+private:
+ template
+ util::Map> loadRecords(MappingInfo& mapping);
+ template
+ void saveRecords(MappingInfo& mapping, util::Map>& records);
+ template void clearCache(util::Map>&cache);
+ template void refreshCache(util::Map>&cache, util::Map>&refreshedCache);
+};
+
+/*
+Function: loadRecords
+Description: Loads all serialized records from the specified
+ shared-memory mapping, deserializes them into
+ application objects, and returns them as a map
+ of tracked records. Each loaded record is marked
+ as CLEAN and assigned its corresponding slot index
+ within the mapping so that future modifications
+ can be written back efficiently.
+Parameter:
+ - mapping: Reference to the mapping containing the
+ serialized records.
+Return type:
+ util::Map>
+ A map containing all loaded records keyed by
+ their unique identifier.
+*/
+template
+util::Map> DataStore::loadRecords(MappingInfo& mapping)
+{
+ util::Map> records;
+ SharedMemory::ensureLatestMapping(mapping);
+ size_t recordCount = SharedMemory::getRecordCount(mapping);
+ for (size_t index = 0; index < recordCount; ++index)
+ {
+ TSerialized* serialized = static_cast(SharedMemory::getRecordAddress(mapping,index));
+ TObject* object = TObject::deserialize(*serialized);
+ TrackedRecord trackedRecord;
+ trackedRecord.data = object;
+ trackedRecord.state = RecordState::CLEAN;
+ trackedRecord.slotIndex = index;
+ records.insert(object->getId(), trackedRecord);
+ }
+ return records;
+}
+
+/*
+Function: saveRecords
+Description: Persists all modified and newly added records
+ contained in the provided map to the specified
+ shared-memory mapping. Modified records overwrite
+ their existing slots, while new records are
+ appended to the end of the mapping. Records marked
+ as CLEAN are ignored.
+Parameter:
+ - mapping: Reference to the mapping where records are
+ stored.
+ - records: Map containing the records to be persisted.
+Return type: void
+*/
+template void DataStore::saveRecords(MappingInfo& mapping, util::Map>& records)
+{
+ SharedMemory::ensureLatestMapping(mapping);
+ for (int index = 0; index < records.getSize(); ++index)
+ {
+ TrackedRecord& record = records.getValueAt(index);
+ if (record.state == RecordState::CLEAN)
+ {
+ continue;
+ }
+ TSerialized serialized = record.data->serialize();
+ if (record.state == RecordState::MODIFIED)
+ {
+ TSerialized* destination = static_cast(SharedMemory::getRecordAddress(mapping, record.slotIndex));
+ if (destination)
+ {
+ *destination = serialized;
+ }
+ }
+ else if (record.state == RecordState::NEW_RECORD)
+ {
+ if (!SharedMemory::ensureCapacityForInsert(mapping))
+ {
+ continue;
+ }
+ size_t recordCount = SharedMemory::getRecordCount(mapping);
+ TSerialized* destination = static_cast(SharedMemory::getRecordAddress(mapping,recordCount));
+ *destination = serialized;
+ SharedMemory::setRecordCount(mapping, recordCount + 1);
+ record.slotIndex = recordCount;
+ }
+ record.state = RecordState::CLEAN;
+ }
+}
+
+/*
+Function: clearCache
+Description: Releases all objects owned by the cache and
+ clears the cache contents.
+Parameters:
+ - cache: Cache to be cleared.
+Returns:
+ - None
+*/
+template
+void DataStore::clearCache(util::Map>&cache)
+{
+ for (int index = 0; index < cache.getSize(); ++index)
+ {
+ delete cache.getValueAt(index).data;
+ cache.getValueAt(index).data = nullptr;
+ }
+ cache.clear();
+}
+
+/*
+Function: refreshCache
+Description: Refreshes the cache while preserving object addresses
+ for records that already exist. Existing objects are
+ updated in-place so that pointers held elsewhere remain
+ valid after the refresh.
+Parameters:
+ - cache: Existing cache to refresh.
+ - refreshedCache: Newly loaded cache contents.
+Returns:
+ - None
+*/
+template
+void DataStore::refreshCache(util::Map>& cache, util::Map>& refreshedCache)
+{
+ util::Map> oldCache = cache;
+ cache.clear();
+ for (int index = 0; index < refreshedCache.getSize(); ++index)
+ {
+ const std::string& id = refreshedCache.getKeyAt(index);
+ TrackedRecord& refreshedRecord = refreshedCache.getValueAt(index);
+ int oldIndex = oldCache.find(id);
+ if (oldIndex != -1)
+ {
+ TrackedRecord& oldRecord = oldCache.getValueAt(oldIndex);
+ *oldRecord.data = *refreshedRecord.data;
+ oldRecord.slotIndex = refreshedRecord.slotIndex;
+ oldRecord.state = refreshedRecord.state;
+ delete refreshedRecord.data;
+ refreshedRecord.data = oldRecord.data;
+ }
+ cache.insert(id, refreshedRecord);
+ }
+ for (int index = 0; index < oldCache.getSize(); ++index)
+ {
+ const std::string& id = oldCache.getKeyAt(index);
+ if (cache.find(id) == -1)
+ {
+ delete oldCache.getValueAt(index).data;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/FileHeader.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/FileHeader.h
new file mode 100644
index 0000000..929dbf4
--- /dev/null
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/FileHeader.h
@@ -0,0 +1,17 @@
+/*
+File: FileHeader.h
+Description: Defines the FileHeader structure used to store
+ metadata for binary record files, including
+ record count and capacity.
+Author: Trenser
+Created: 10-June-2026
+*/
+
+#pragma once
+#include
+
+struct FileHeader
+{
+ size_t recordCount;
+ size_t capacity;
+};
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/MappingInfo.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/MappingInfo.h
new file mode 100644
index 0000000..ebd5123
--- /dev/null
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/MappingInfo.h
@@ -0,0 +1,29 @@
+/*
+File: MappingInfo.h
+Description: Defines the MappingInfo structure used for
+ managing Windows file mapping operations.
+ Stores handles, mapped view pointer,
+ file metadata, and capacity information.
+Author: Trenser
+Created: 10-June-2026
+*/
+
+#pragma once
+#include
+#include
+
+struct MappingInfo
+{
+ HANDLE fileHandle;
+ HANDLE mappingHandle;
+ void* mappedView;
+ std::string fileName;
+ size_t recordSize;
+ size_t mappedCapacity;
+ MappingInfo()
+ : fileHandle(NULL),
+ mappingHandle(NULL),
+ mappedView(nullptr),
+ recordSize(0),
+ mappedCapacity(0) {}
+};
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/RecordState.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/RecordState.h
new file mode 100644
index 0000000..95402fd
--- /dev/null
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/RecordState.h
@@ -0,0 +1,17 @@
+/*
+File: RecordState.h
+Description: Defines the RecordState enumeration used to
+ represent the state of a record in storage.
+ States include CLEAN, NEW_RECORD, and MODIFIED.
+Author: Trenser
+Created: 10-June-2026
+*/
+
+#pragma once
+
+enum class RecordState : int
+{
+ CLEAN,
+ NEW_RECORD,
+ MODIFIED
+};
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/SerializedRecords.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/SerializedRecords.h
new file mode 100644
index 0000000..2d18842
--- /dev/null
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/SerializedRecords.h
@@ -0,0 +1,109 @@
+/*
+File: SerializedRecords.h
+Description: Defines serialized structures for persistent storage
+ and retrieval of system entities including User,
+ Notification, Service, ComboPackage, InventoryItem,
+ ServiceBooking, JobCard, Invoice, and Observer.
+ These structures use fixed-size character arrays
+ and primitive types for binary serialization.
+Author: Trenser
+Created: 10-June-2026
+*/
+
+#pragma once
+#include "Utility.h"
+#include "Enums.h"
+#include "Timestamp.h"
+
+struct SerializedUser
+{
+ char id[64];
+ char username[64];
+ char password[64];
+ char name[128];
+ char phone[32];
+ char email[128];
+ util::UserType userType;
+ util::State status;
+};
+
+struct SerializedNotification
+{
+ char id[64];
+ char recipientUserId[64];
+ char title[128];
+ char message[1024];
+ util::Timestamp createdAt;
+ util::State state;
+};
+
+struct SerializedService
+{
+ char id[64];
+ char name[128];
+ char inventoryItemIDs[1024];
+ double laborCost;
+ util::State status;
+};
+
+struct SerializedComboPackage
+{
+ char id[64];
+ char packageName[128];
+ double discountPercentage;
+ char serviceIDs[1024];
+ util::State status;
+};
+
+struct SerializedInventoryItem
+{
+ char id[64];
+ char partName[128];
+ int quantity;
+ double price;
+ util::State status;
+};
+
+struct SerializedServiceBooking
+{
+ char id[64];
+ util::ServiceJobStatus status;
+ char serviceIDs[1024];
+ char customerId[64];
+ char vehicleNumber[64];
+ char vehicleBrand[64];
+ char vehicleModel[64];
+ char assignedTechnicianId[64];
+ double discountPercentage;
+};
+
+struct SerializedJobCard
+{
+ char id[64];
+ char bookingId[64];
+ char serviceId[64];
+ char technicianId[64];
+ util::Timestamp assignedDate;
+ util::ServiceJobStatus status;
+ util::Timestamp completionDate;
+};
+
+struct SerializedInvoice
+{
+ char id[64];
+ char bookingId[64];
+ util::Timestamp invoiceDate;
+ char partIDs[1024];
+ double laborCost;
+ double partsCost;
+ double discountPercentage;
+ double totalAmount;
+ util::Timestamp paymentDate;
+ util::PaymentMode paymentMethod;
+ util::PaymentStatus status;
+};
+
+struct SerializedObserver
+{
+ char id[64];
+};
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/SharedMemory.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/SharedMemory.cpp
new file mode 100644
index 0000000..6a10c9f
--- /dev/null
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/SharedMemory.cpp
@@ -0,0 +1,385 @@
+/*
+File: SharedMemory.cpp
+Description: Implements shared memory utilities for managing
+ Windows file mapping operations. Provides functions
+ to create, open, resize, and close mappings, as well
+ as access headers, records, and ensure synchronization
+ across processes.
+Author: Trenser
+Created: 11-June-2026
+*/
+
+#include "SharedMemory.h"
+#include "Config.h"
+
+/*
+Function: invalidateMapping
+Description: Releases all mapping resources and resets the mapping to an invalid state.
+Parameters:
+ - mapping: MappingInfo&, mapping information and handles
+Returns:
+ - None
+*/
+static void invalidateMapping(MappingInfo& mapping)
+{
+ if (mapping.mappedView != nullptr)
+ {
+ UnmapViewOfFile(mapping.mappedView);
+ mapping.mappedView = nullptr;
+ }
+ if (mapping.mappingHandle != NULL)
+ {
+ CloseHandle(mapping.mappingHandle);
+ mapping.mappingHandle = NULL;
+ }
+ if (mapping.fileHandle != INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(mapping.fileHandle);
+ mapping.fileHandle = INVALID_HANDLE_VALUE;
+ }
+ mapping.mappedCapacity = 0;
+}
+
+/*
+Function: createOrOpenMapping
+Description: Creates or opens a file mapping and maps it into the process address space.
+Parameters:
+ - mapping: MappingInfo&, mapping information and handles
+Returns:
+ - bool: True if the mapping was successfully created/opened, otherwise false
+*/
+bool SharedMemory::createOrOpenMapping(MappingInfo& mapping)
+{
+ if (mapping.recordSize == 0)
+ {
+ return false;
+ }
+ mapping.fileHandle =
+ CreateFileA(
+ mapping.fileName.c_str(),
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (mapping.fileHandle == INVALID_HANDLE_VALUE)
+ {
+ return false;
+ }
+ LARGE_INTEGER fileSize;
+ if (!GetFileSizeEx(mapping.fileHandle, &fileSize))
+ {
+ invalidateMapping(mapping);
+ return false;
+ }
+ bool isNewFile = (fileSize.QuadPart == 0);
+ const size_t initialCapacity = config::file::INITIAL_CAPACITY;
+ if (isNewFile)
+ {
+ LARGE_INTEGER newSize;
+ newSize.QuadPart = sizeof(FileHeader) + initialCapacity * mapping.recordSize;
+ if (!SetFilePointerEx(mapping.fileHandle, newSize, NULL, FILE_BEGIN))
+ {
+ invalidateMapping(mapping);
+ return false;
+ }
+ if (!SetEndOfFile(mapping.fileHandle))
+ {
+ invalidateMapping(mapping);
+ return false;
+ }
+ }
+ mapping.mappingHandle =
+ CreateFileMappingA(
+ mapping.fileHandle,
+ NULL,
+ PAGE_READWRITE,
+ 0,
+ 0,
+ NULL);
+ if (mapping.mappingHandle == NULL)
+ {
+ invalidateMapping(mapping);
+ return false;
+ }
+ mapping.mappedView =
+ MapViewOfFile(
+ mapping.mappingHandle,
+ FILE_MAP_ALL_ACCESS,
+ 0,
+ 0,
+ 0);
+ if (mapping.mappedView == nullptr)
+ {
+ invalidateMapping(mapping);
+ return false;
+ }
+ FileHeader* header = getHeader(mapping);
+ if (header == nullptr)
+ {
+ invalidateMapping(mapping);
+ return false;
+ }
+ if (isNewFile)
+ {
+ header->recordCount = 0;
+ header->capacity = initialCapacity;
+ }
+ mapping.mappedCapacity = header->capacity;
+ return true;
+}
+
+/*
+Function: closeMapping
+Description: Unmaps and closes all resources associated with a file mapping.
+Parameters:
+ - mapping: MappingInfo&, mapping to close
+Returns:
+ - None
+*/
+void SharedMemory::closeMapping(MappingInfo& mapping)
+{
+ invalidateMapping(mapping);
+}
+
+/*
+Function: getHeader
+Description: Returns the file header stored at the beginning of the mapped memory region.
+Parameters:
+ - mapping: MappingInfo&, mapping information and handles
+Returns:
+ - FileHeader*: Pointer to the file header, or nullptr if the mapping is not valid
+*/
+FileHeader* SharedMemory::getHeader(MappingInfo& mapping)
+{
+ if (mapping.mappedView == nullptr)
+ {
+ return nullptr;
+ }
+ return reinterpret_cast(mapping.mappedView);
+}
+
+/*
+Function: getRecordAddress
+Description: Returns the address of a record at the specified index within the mapped memory region.
+Parameters:
+ - mapping: MappingInfo&, mapping information and handles
+ - index: size_t, record index
+Returns:
+ - void*: Pointer to the record, or nullptr if the mapping is not valid
+*/
+void* SharedMemory::getRecordAddress(MappingInfo& mapping, size_t index)
+{
+ if (mapping.mappedView == nullptr)
+ {
+ return nullptr;
+ }
+ return reinterpret_cast(mapping.mappedView) + sizeof(FileHeader) + index * mapping.recordSize;
+}
+
+/*
+Function: getRecordCount
+Description: Returns the number of records currently stored in the mapping.
+Parameters:
+ - mapping: MappingInfo&, mapping information and handles
+Returns:
+ - size_t: Number of records in the mapping
+*/
+size_t SharedMemory::getRecordCount(MappingInfo& mapping)
+{
+ FileHeader* header = getHeader(mapping);
+ if (header == nullptr)
+ {
+ return 0;
+ }
+ return header->recordCount;
+}
+
+/*
+Function: setRecordCount
+Description: Updates the number of records stored in the mapping.
+Parameters:
+ - mapping: MappingInfo&, mapping information and handles
+ - count: size_t, new record count
+Returns:
+ - None
+*/
+void SharedMemory::setRecordCount(MappingInfo& mapping, size_t count)
+{
+ FileHeader* header = getHeader(mapping);
+ if (header == nullptr)
+ {
+ return;
+ }
+ header->recordCount = count;
+}
+
+/*
+Function: getCapacity
+Description: Returns the current capacity of the mapping.
+Parameters:
+ - mapping: MappingInfo&, mapping information and handles
+Returns:
+ - size_t: Maximum number of records that can be stored in the mapping
+*/
+size_t SharedMemory::getCapacity(MappingInfo& mapping)
+{
+ FileHeader* header = getHeader(mapping);
+ if (header == nullptr)
+ {
+ return 0;
+ }
+ return header->capacity;
+}
+
+/*
+Function: resizeMapping
+Description: Resizes the file mapping to the specified capacity.
+Parameters:
+ - mapping: MappingInfo&, mapping information and handles
+ - newCapacity: size_t, new mapping capacity
+Returns:
+ - bool: True if the resize succeeded, otherwise false
+*/
+bool SharedMemory::resizeMapping(MappingInfo& mapping, size_t newCapacity)
+{
+ FileHeader* header = getHeader(mapping);
+ if (header == nullptr)
+ {
+ invalidateMapping(mapping);
+ return false;
+ }
+ header->capacity = newCapacity;
+ if (!FlushViewOfFile(mapping.mappedView, sizeof(FileHeader)))
+ {
+ return false;
+ }
+ if (!UnmapViewOfFile(mapping.mappedView))
+ {
+ return false;
+ }
+ mapping.mappedView = nullptr;
+ CloseHandle(mapping.mappingHandle);
+ mapping.mappingHandle = NULL;
+ LARGE_INTEGER newSize;
+ newSize.QuadPart = sizeof(FileHeader) + newCapacity * mapping.recordSize;
+ if (!SetFilePointerEx(mapping.fileHandle, newSize, NULL, FILE_BEGIN))
+ {
+ invalidateMapping(mapping);
+ return false;
+ }
+ if (!SetEndOfFile(mapping.fileHandle))
+ {
+ invalidateMapping(mapping);
+ return false;
+ }
+ mapping.mappingHandle =
+ CreateFileMappingA(
+ mapping.fileHandle,
+ NULL,
+ PAGE_READWRITE,
+ 0,
+ 0,
+ NULL);
+ if (mapping.mappingHandle == NULL)
+ {
+ invalidateMapping(mapping);
+ return false;
+ }
+ mapping.mappedView =
+ MapViewOfFile(
+ mapping.mappingHandle,
+ FILE_MAP_ALL_ACCESS,
+ 0,
+ 0,
+ 0);
+ if (mapping.mappedView == nullptr)
+ {
+ invalidateMapping(mapping);
+ return false;
+ }
+ mapping.mappedCapacity = newCapacity;
+ return true;
+}
+
+/*
+Function: ensureCapacityForInsert
+Description: Ensures that the mapping has space for at least one additional record, growing it if necessary.
+Parameters:
+ - mapping: MappingInfo&, mapping information and handles
+Returns:
+ - bool: True if capacity is available, otherwise false
+*/
+bool SharedMemory::ensureCapacityForInsert(MappingInfo& mapping)
+{
+ size_t recordCount = getRecordCount(mapping);
+ size_t capacity = getCapacity(mapping);
+ if (recordCount < capacity)
+ {
+ return true;
+ }
+ return resizeMapping(mapping, capacity * 2);
+}
+
+/*
+Function: ensureLatestMapping
+Description: Remaps the file if another process has resized it.
+Parameters:
+ - mapping: MappingInfo&, mapping information and handles
+Returns:
+ - bool: True if the mapping is valid and up to date, otherwise false
+*/
+bool SharedMemory::ensureLatestMapping(MappingInfo& mapping)
+{
+ FileHeader* header = getHeader(mapping);
+ if (header == nullptr)
+ {
+ return false;
+ }
+ if (header->capacity == mapping.mappedCapacity)
+ {
+ return true;
+ }
+ if (!UnmapViewOfFile(mapping.mappedView))
+ {
+ invalidateMapping(mapping);
+ return false;
+ }
+ mapping.mappedView = nullptr;
+ CloseHandle(mapping.mappingHandle);
+ mapping.mappingHandle = NULL;
+ mapping.mappingHandle =
+ CreateFileMappingA(
+ mapping.fileHandle,
+ NULL,
+ PAGE_READWRITE,
+ 0,
+ 0,
+ NULL);
+ if (mapping.mappingHandle == NULL)
+ {
+ invalidateMapping(mapping);
+ return false;
+ }
+ mapping.mappedView =
+ MapViewOfFile(
+ mapping.mappingHandle,
+ FILE_MAP_ALL_ACCESS,
+ 0,
+ 0,
+ 0);
+ if (mapping.mappedView == nullptr)
+ {
+ invalidateMapping(mapping);
+ return false;
+ }
+ header = getHeader(mapping);
+ if (header == nullptr)
+ {
+ invalidateMapping(mapping);
+ return false;
+ }
+ mapping.mappedCapacity = header->capacity;
+ return true;
+}
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/SharedMemory.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/SharedMemory.h
new file mode 100644
index 0000000..a288ab3
--- /dev/null
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/SharedMemory.h
@@ -0,0 +1,29 @@
+/*
+File: SharedMemory.h
+Description: Declares functions for managing Windows file
+ mapping and shared memory operations. Provides
+ utilities for creating, resizing, and closing
+ mappings, as well as accessing headers and
+ record data.
+Author: Trenser
+Created: 10-June-2026
+*/
+
+#pragma once
+#include
+#include "MappingInfo.h"
+#include "FileHeader.h"
+
+namespace SharedMemory
+{
+ bool createOrOpenMapping(MappingInfo& mapping);
+ void closeMapping(MappingInfo& mapping);
+ bool ensureLatestMapping(MappingInfo& mapping);
+ bool resizeMapping(MappingInfo& mapping, size_t newCapacity);
+ FileHeader* getHeader(MappingInfo& mapping);
+ void* getRecordAddress(MappingInfo& mapping, size_t index);
+ size_t getRecordCount(MappingInfo& mapping);
+ void setRecordCount(MappingInfo& mapping, size_t count);
+ size_t getCapacity(MappingInfo& mapping);
+ bool ensureCapacityForInsert(MappingInfo& mapping);
+};
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/TrackedRecord.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/TrackedRecord.h
new file mode 100644
index 0000000..5ff9ac9
--- /dev/null
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/datastores/sharedmemory/TrackedRecord.h
@@ -0,0 +1,33 @@
+/*
+File: TrackedRecord.h
+Description: Defines the TrackedRecord template structure used
+ to manage objects with associated record state and
+ slot index. Supports tracking of CLEAN, NEW_RECORD,
+ and MODIFIED states for persistence and synchronization.
+Author: Trenser
+Created: 10-June-2026
+*/
+
+#pragma once
+#include "RecordState.h"
+
+static const size_t INVALID_SLOT = static_cast(-1);
+
+template
+struct TrackedRecord
+{
+ T* data;
+ RecordState state;
+ size_t slotIndex;
+ TrackedRecord()
+ : data(nullptr),
+ state(RecordState::CLEAN),
+ slotIndex(INVALID_SLOT) {}
+ TrackedRecord(
+ T* object,
+ RecordState recordState,
+ size_t slot)
+ : data(object),
+ state(recordState),
+ slotIndex(slot) {}
+};
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.h
index 6b9f518..b448872 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/services/UserManagementService.h
@@ -6,6 +6,7 @@ Description: Header file declaring the UserManagementService class, which manage
Author: Trenser
Date:19-May-2026
*/
+
#pragma once
#include
#include "Map.h"
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Config.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Config.h
index b0bd19d..2eef19d 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Config.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Config.h
@@ -28,16 +28,18 @@ namespace config
namespace file
{
- constexpr const char* INVENTORYITEM_FILE = "files/InventoryItem.csv";
- constexpr const char* USER_FILE = "files/User.csv";
- constexpr const char* NOTIFICATION_FILE = "files/Notification.csv";
- constexpr const char* SERVICE_FILE = "files/Service.csv";
- constexpr const char* COMBOPACKAGE_FILE = "files/ComboPackage.csv";
- constexpr const char* SERVICEBOOKING_FILE = "files/ServiceBooking.csv";
- constexpr const char* JOBCARD_FILE = "files/JobCard.csv";
- constexpr const char* INVOICE_FILE = "files/Invoice.csv";
- constexpr const char* SERVICEMANAGEMENTOBSERVERS = "files/ServiceManagementObservers.csv";
- constexpr const char* PAYMENTMANAGEMENTOBSERVERS = "files/PaymentManagementObservers.csv";
- constexpr const char* INVENTORYMANAGEMENTOBSERVERS = "files/InventoryManagementObservers.csv";
+ const size_t INITIAL_CAPACITY = 100;
+ constexpr const char* DIRECTORY = "files/";
+ constexpr const char* INVENTORYITEM_FILE = "files/InventoryItem.dat";
+ constexpr const char* USER_FILE = "files/User.dat";
+ constexpr const char* NOTIFICATION_FILE = "files/Notification.dat";
+ constexpr const char* SERVICE_FILE = "files/Service.dat";
+ constexpr const char* COMBOPACKAGE_FILE = "files/ComboPackage.dat";
+ constexpr const char* SERVICEBOOKING_FILE = "files/ServiceBooking.dat";
+ constexpr const char* JOBCARD_FILE = "files/JobCard.dat";
+ constexpr const char* INVOICE_FILE = "files/Invoice.dat";
+ constexpr const char* SERVICEMANAGEMENTOBSERVERS = "files/ServiceManagementObservers.dat";
+ constexpr const char* PAYMENTMANAGEMENTOBSERVERS = "files/PaymentManagementObservers.dat";
+ constexpr const char* INVENTORYMANAGEMENTOBSERVERS = "files/InventoryManagementObservers.dat";
}
}
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Enums.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Enums.h
index 7585abc..b908f51 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Enums.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Enums.h
@@ -12,28 +12,28 @@ Date: 19-May-2026
namespace util
{
- enum class UserType
+ enum class UserType : int
{
ADMIN,
TECHNICIAN,
CUSTOMER
};
- enum class PaymentMode
+ enum class PaymentMode : int
{
ONLINE,
OFFLINE,
NOTSET
};
- enum class PaymentStatus
+ enum class PaymentStatus : int
{
PENDING,
COMPLETED,
PAID
};
- enum class ServiceJobStatus
+ enum class ServiceJobStatus : int
{
PENDING,
STARTED,
@@ -42,7 +42,7 @@ namespace util
CANCELLED
};
- enum class State
+ enum class State : int
{
ACTIVE,
INACTIVE
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/FileHelper.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/FileHelper.h
index 2b3e94a..c8bf96f 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/FileHelper.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/FileHelper.h
@@ -106,4 +106,4 @@ namespace util
file << records[index] << '\n';
}
}
-}
+}
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/InputHelper.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/InputHelper.h
index 75d8bbc..dffc199 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/InputHelper.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/InputHelper.h
@@ -10,6 +10,7 @@
#include
#include
#include
+#include
namespace util
{
@@ -54,6 +55,48 @@ namespace util
value = cleanedValue;
}
+ /*
+ * Function: readPassword
+ * Description: Reads a password from console without echoing characters;
+ * displays '*' for each character typed, handles backspace,
+ * and cleans commas from the result.
+ * Parameters:
+ * value - reference to a string where the password will be stored
+ * Returns:
+ * void - no return value
+ */
+ inline void readPassword(std::string& value)
+ {
+ value.clear();
+ char currentCharacter;
+ while ((currentCharacter = _getch()) != '\r')
+ {
+ if (currentCharacter == '\b')
+ {
+ if (!value.empty())
+ {
+ value.pop_back();
+ std::cout << "\b \b";
+ }
+ }
+ else
+ {
+ value += currentCharacter;
+ std::cout << '*';
+ }
+ }
+ std::cout << std::endl;
+ std::string cleanedValue;
+ for (int iterator = 0; iterator < value.length(); iterator++)
+ {
+ if (value[iterator] != ',')
+ {
+ cleanedValue += value[iterator];
+ }
+ }
+ value = cleanedValue;
+ }
+
/*
* Function: pressEnter
* Description: Pauses execution until the user presses Enter.
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Utility.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Utility.h
index 300d5c4..9b6bc9d 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Utility.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/utilities/Utility.h
@@ -99,4 +99,80 @@ namespace util
auto observerIDs = service->getObserverIDs();
util::saveRecords(filePath, observerIDs);
}
+
+ template
+ Map getObjects(const Map>& trackedRecords);
+
+ template
+ Map getConstObjects(const Map>& trackedRecords);
+
+ template
+ TrackedRecord createNewRecord(TObject* object);
+}
+
+/*
+Function: getObjects
+Description: Extracts the object pointers from a tracked-record
+ collection and returns them as a map keyed by the
+ same identifiers.
+Parameters:
+ - trackedRecords: Collection of tracked records.
+Returns:
+ - Map: Collection of object pointers.
+*/
+template
+util::Map util::getObjects(const util::Map>& trackedRecords)
+{
+ util::Map objects;
+ for (int index = 0; index < trackedRecords.getSize(); ++index)
+ {
+ const std::string& key = trackedRecords.getKeyAt(index);
+ TObject* object = trackedRecords.getValueAt(index).data;
+ objects.insert(key, object);
+ }
+ return objects;
+}
+
+/*
+Function: getConstObjects
+Description: Extracts the object pointers from a tracked-record
+ collection and returns them as a read-only map
+ keyed by the same identifiers.
+Parameters:
+ - trackedRecords: Collection of tracked records.
+Returns:
+ - Map:
+ Collection of read-only object pointers.
+*/
+template
+util::Map util::getConstObjects(
+ const util::Map>& trackedRecords)
+{
+ util::Map objects;
+ for (int index = 0; index < trackedRecords.getSize(); ++index)
+ {
+ const std::string& key = trackedRecords.getKeyAt(index);
+ const TObject* object = trackedRecords.getValueAt(index).data;
+ objects.insert(key, object);
+ }
+ return objects;
+}
+
+/*
+Function: createNewRecord
+Description: Creates a tracked record for a newly created
+ object. The record is initialized with
+ NEW_RECORD state.
+Parameters:
+ - object: Pointer to the newly created object.
+Returns:
+ - TrackedRecord: Initialized tracked record.
+*/
+template
+TrackedRecord util::createNewRecord(TObject* object)
+{
+ TrackedRecord record;
+ record.data = object;
+ record.state = RecordState::NEW_RECORD;
+ return record;
}
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp
index 3e56d99..0d60f97 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/CustomerMenu.cpp
@@ -30,7 +30,6 @@ Description: Displays the customer menu and handles user input until logout is s
Parameter: None
Return type: void
*/
-
void CustomerMenu::showMenu()
{
while (true)
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/MenuHelper.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/MenuHelper.h
index 83720c0..c6ebaa6 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/MenuHelper.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/MenuHelper.h
@@ -914,7 +914,7 @@ inline void changePasswordHelper(Controller& controller)
util::clear();
std::cout << "Change Password\n";
std::cout << "Enter new password: ";
- util::read(newPassword);
+ util::readPassword(newPassword);
if (!util::isPasswordValid(newPassword))
{
std::cout << "Error: Password is not strong enough!\n";
@@ -928,7 +928,7 @@ inline void changePasswordHelper(Controller& controller)
continue;
}
std::cout << "Confirm new password: ";
- util::read(confirmedPassword);
+ util::readPassword(confirmedPassword);
if (confirmedPassword != newPassword)
{
std::cout << "Passwords are different. Try again\n";
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/TechnicianMenu.h b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/TechnicianMenu.h
index a17ccb1..2d118a0 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/TechnicianMenu.h
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/TechnicianMenu.h
@@ -22,4 +22,4 @@ public:
void viewNotifications();
void logout();
void changePassword();
-};
+};
\ No newline at end of file
diff --git a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/UserInterface.cpp b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/UserInterface.cpp
index 841e2ea..4596d9b 100644
--- a/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/UserInterface.cpp
+++ b/Trenser.VehicleServiceSystem/Trenser.VehicleServiceSystem/views/UserInterface.cpp
@@ -106,7 +106,7 @@ void UserInterface::login()
std::cout << "Enter username: ";
util::read(username);
std::cout << "Enter password: ";
- util::read(password);
+ util::readPassword(password);
if (m_controller.login(username, password))
{
const User* authenticatedUser = m_controller.getAuthenticatedUser();
@@ -167,7 +167,7 @@ void UserInterface::registerCustomer()
return;
}
std::cout << "Enter password: ";
- util::read(password);
+ util::readPassword(password);
if (!util::isPasswordValid(password))
{
std::cout << "Error: Password is invalid!";
@@ -185,4 +185,4 @@ void UserInterface::registerCustomer()
m_controller.createCustomer(username, name, password, email, phone);
std::cout << "Registration is successful";
util::pressEnter();
-}
+}
\ No newline at end of file