Changes
- Added Controller::removeServiceBooking() with documentation and delegation to ServiceManagementService.
- Implemented ServiceManagementService::removeServiceBooking() to handle cancellation of pending bookings, enforce status validation, send notifications, and persist changes safely.
- Updated CustomerMenu to include a "Cancel Service Booking" option, wired into handleOperation, and implemented CustomerMenu::cancelServiceBooking() for user interaction.
- Ensured consistent declarations in Controller.h, ServiceManagementService.h, and CustomerMenu.h.
- Refactored ServiceManagementService::updateJobStatus() to use tracked job card references instead of raw pointers, ensuring consistent state updates.
- Added proper null checks and error handling for current job retrieval to prevent unexpected termination.
- Updated logic to mark tracked job records as MODIFIED when status transitions occur (`STARTED` → `IN_PROGRESS`, `IN_PROGRESS` → `COMPLETED`).
- Simplified control flow and indentation for better readability and maintainability.
- Added retrieval of tracked service bookings and inventory items in ServiceManagementService::createJobCard().
- Validated service booking ID and inventory item indices before proceeding with job card creation.
- Decremented inventory item quantities when job cards are created and marked corresponding tracked inventory records as `MODIFIED`.
- Updated tracked service booking state to `MODIFIED` when technician is assigned and job status changes.
- Persisted changes by saving job cards, service bookings, and inventory items to the datastore.
Fixes
#2105#2076#2075#2074
**Changes:**
- Persist service bookings immediately after purchase to ensure data consistency.
- Enhanced notification display by appending authenticated user names to notification titles.
- Updated account disabled event handling to include authenticated user names in warning messages.
- Modified notification event handling in Admin, Customer, and Technician menus to pass authenticated user names.
- Improved service selection logic to skip services with depleted inventory items.
- Added dependency cleanup: services requiring a removed inventory item are automatically removed.
- Updated displayNewNotification to extract numeric IDs correctly and append authenticated user names to notification titles.
- Included StringHelper for improved string operations in notification handling.
#2080#2081#2082
Related work items: #2080, #2081, #2082
Changes:
- Fixed DataStore cache refresh from overwriting records with pending local modifications.
- Fixed notification ID collisions by refreshing the notification cache before creating new notifications.
- Added authorization state tracking to authenticated sessions.
- Revoked authorization immediately when account-disabled events are received.
- Added authorization validation for protected service operations.
- Cleared authorization state during logout.
- Added admin notifications for newly created service bookings.
- Added admin notifications for newly created combo package bookings.
- Included Service Booking IDs in admin notification messages.
#2077#2078#2078#2100
Related work items: #2077, #2078, #2079, #2100
Changes:
- Added Controller::removeServiceBooking() with proper documentation and
delegation to ServiceManagementService.
- Implemented ServiceManagementService::removeServiceBooking() to handle
cancellation of pending bookings, enforce status validation, send
notifications, and persist changes safely.
- Updated CustomerMenu to include a "Cancel Service Booking" option in
the menu, wired it into handleOperation, and implemented
CustomerMenu::cancelServiceBooking() for user interaction.
- Ensured consistent declarations in Controller.h,
ServiceManagementService.h, and CustomerMenu.h.
Fixes#2105
Changes:
- Added m_dataStore.saveServiceBookings() in ServiceManagementService::purchaseService() to persist bookings immediately after successful purchase.
- Enhanced AdminMenu::removeInventoryItem() to also remove all services that depend on the removed inventory item, ensuring consistency between inventory and service availability.
- Updated selectServiceFromServices() in MenuHelper.h to skip services if any of their required inventory items have a quantity less than 1, preventing users from selecting unavailable services.
- Introduced inventory depletion checks before inserting services into the active services map, improving reliability of service selection.
Fixes #2082
Changes:
- Added notifyAllAdmins() helper in ServiceManagementService.
- Sent notifications to all administrators when a customer places a service booking.
- Sent notifications to all administrators when a customer purchases a combo package.
- Included the generated Service Booking ID in admin notifications.
Fixes#2100
Changes:
- Refactored ServiceManagementService::updateJobStatus() to use tracked
job card references instead of raw pointers, ensuring consistent state
updates.
- Added proper null checks and error handling for current job retrieval
to prevent unexpected termination.
- Updated logic to mark tracked job records as MODIFIED when status
transitions occur (STARTED → IN_PROGRESS, IN_PROGRESS → COMPLETED).
- Simplified control flow and indentation for better readability and
maintainability.
Fixes#2076
Changes:
- Added authorization state tracking to authenticated sessions.
- Revoked authorization immediately when an account-disabled event is received.
- Added authorization validation before protected service operations.
- Cleared authorization state on logout.
Fixes#2078
Changes:
- Added retrieval of tracked service bookings and inventory items in
ServiceManagementService::createJobCard().
- Validated service booking ID and inventory item indices before
proceeding with job card creation.
- Decremented inventory item quantities when job cards are created and
marked corresponding tracked inventory records as MODIFIED.
- Updated tracked service booking state to MODIFIED when technician is
assigned and job status changes.
- Persisted changes by saving job cards, service bookings, and inventory
items to the datastore.
Fixes#2075
Changes:
- Added #include "StringHelper.h" to MenuHelper.h for utility functions.
- Updated displayNewNotification() to compare notification IDs using util::extractNumber() instead of raw string comparison.
- Ensured numeric ordering of notifications by extracting and comparing integer values from IDs.
- Preserved existing notification selection logic while improving accuracy of ID comparisons.
Fixes#2081
Changes:
- Updated ServiceManagementService::purchaseService() to persist service
bookings immediately after creation using m_dataStore.saveServiceBookings().
- Updated ServiceManagementService::purchaseComboPackage() to persist
combo package bookings immediately after creation using
m_dataStore.saveServiceBookings().
- Changed DataStore::getJobCards() to use a reference for tracked bookings
to ensure consistent linkage and prevent overwriting.
Fixes#2074
Changes:
- Updated AdminMenu::handleNotificationEvent, CustomerMenu::handleNotificationEvent, and TechnicianMenu::handleNotificationEvent to retrieve the authenticated user and pass their name to displayNewNotification().
- Modified Menu::handleAccountDisabledEvent to append the authenticated user’s name to the message box title when available.
- Refactored displayNewNotification() in MenuHelper.h to accept the authenticated user’s name as an additional parameter.
- Enhanced notification display logic to append the user’s name to the notification title when present.
- Added null checks to ensure safe handling when no authenticated user exists.
FIxes#2080
Changes:
- Retrieved the notifications map before creating a new notification in sendNotification().
- Ensured the notification cache is refreshed before generating a notification ID.
- Prevented newly created notifications from overwriting notifications added by other operations prior to save.
Fixes#2079
Changes:
- Added a check for RecordState::MODIFIED in DataStore::refreshCache().
- Preserved modified cache records during refresh instead of overwriting them with datastore values.
- Discarded refreshed records when a corresponding cached record has pending changes.
Fixes#2077
Implement interprocess event handling for notifications and account disable
Changes:
- Implements #2061
- Introduce EventManager for user-specific Windows event publishing/listening
- Add real-time notification and account-disabled event propagation
- Register authentication events through Controller and AuthenticationManagementService
- Trigger notification events from Inventory, Payment, and Service Management modules
- Trigger account-disabled events when users are deactivated
- Extract common menu event listener logic into Menu base class
- Add notification popup handling for Admin, Customer, and Technician menus
- Refactor shared memory components into core/sharedmemory
- Update project structure and include paths for events and shared memory modules
Related work items: #1928, #2061
Changes:
- Implements #2061
- Introduce EventManager for user-specific Windows event publishing/listening
- Add real-time notification and account-disabled event propagation
- Register authentication events through Controller and AuthenticationManagementService
- Trigger notification events from Inventory, Payment, and Service Management modules
- Trigger account-disabled events when users are deactivated
- Extract common menu event listener logic into Menu base class
- Add notification popup handling for Admin, Customer, and Technician menus
- Refactor shared memory components into core/sharedmemory
- Update project structure and include paths for events and shared memory modules
User Story #1949
User Story #1950
**Changes**
* Added `DataStoreLockGuard` header to project configuration and implemented the class for scoped mutex management.
* Refactored `Invoice` model to replace CSV-based serialization with `SerializedInvoice` struct, removing legacy `getHeaders()` and string parsing logic.
* Updated `DataStore::getInvoices()` to load records via `loadRecords`, refresh cache, and automatically enrich `Invoice` objects with linked `ServiceBooking` and `InventoryItem` entities.
* Implemented `DataStore::saveInvoices()` using the `saveRecords<Invoice, SerializedInvoice>` template for direct shared memory persistence.
* Integrated `DataStoreLockGuard` across all critical methods in `PaymentManagementService`: `sendPaymentReminders`, `generateInvoice`, `getInvoices`, `completePayment`, `getAllInvoices`, and `confirmPayment`.
* Refactored invoice creation and modification flows to use `createNewRecord` for insertion and explicitly set `RecordState::MODIFIED` before triggering `saveInvoices()`.
* Updated data access patterns to extract `.data` pointers from `TrackedRecord` wrappers instead of accessing raw map values directly.
* Added validation logic in `getInvoices()` to throw `runtime_error` if referenced ServiceBookings or InventoryItems are missing.
* Added necessary header dependencies (`Invoice.h`, `DataStoreLockGuard.h`) in service and store layers.
Related work items: #1930, #1949, #1950
User Story #1957
User Story #1958
**Changes**
- Added DataStoreLockGuard for scoped datastore locking/unlocking.
- Refactored InventoryItem serialization from CSV strings to SerializedInventoryItem struct.
- Removed old serialize, deserialize, and getHeaders methods from InventoryItem.
- Updated DataStore to load, refresh, and save inventory items using typed records.
- Applied lock guard in InventoryManagementService for stock alerts, add/remove/update operations.
- Enhanced error handling for invalid item IDs and missing inventory records.
- Simplified getInventoryItems to return object maps from tracked records.
- Removed redundant persistence methods (loadInventoryItems, saveInventoryItems) from service layer.
Related work items: #1926, #1957, #1958
User Story #1955
User Story #1956
**Changes**
* Added `DataStoreLockGuard` class to provide scoped automatic locking and unlocking for the datastore.
* Refactored `Service`, `ServiceBooking`, `JobCard`, and `ComboPackage` models to replace CSV-based serialization with fixed-size `Serialized*` struct records.
* Removed legacy `serialize()`, `deserialize()`, and `getHeaders()` methods from all affected model classes.
* Updated `DataStore` getter methods (`getServices`, `getComboPackages`, `getServiceBookings`, `getJobCards`) to load records from shared memory and automatically enrich them with linked entities (inventory items, services, bookings, users).
* Implemented generic save helpers (`saveServices`, `saveComboPackages`, etc.) using the `saveRecords` template to persist tracked records directly.
* Integrated `DataStoreLockGuard` into critical `ServiceManagementService` methods including `purchaseService`, `purchaseComboPackage`, `createService`, `removeService`, `cancelCustomerServiceBookings`, and `updateJobStatus`.
* Refactored cancellation workflows (`cancelCustomerServiceBookings`, `cancelTechnicianJobs`) to use `TrackedRecord` objects, correctly marking states as `MODIFIED` before persisting changes.
* Updated inventory restoration logic to accept tracked inventory maps and increment quantities while updating record states.
* Modified service layer access patterns to extract `.data` pointers from `TrackedRecord` wrappers instead of accessing raw map values directly.
* Added necessary header dependencies (`DataStoreLockGuard.h`, `SerializedRecords.h`) across data store and service layers.
* Removed redundant manual persistence calls in the service layer, relying on explicit `save*` calls after modifications within locked scopes.
Related work items: #1927, #1955, #1956
User Story #1951
User Story #1952
**Changes**
- Added DataStoreLockGuard for scoped locking/unlocking.
- Applied lock guard in AuthenticationManagementService (login, password change).
- Switched User serialization from CSV to SerializedUser struct.
- Removed old CSV-based serialize, deserialize, and getHeaders.
- Updated DataStore::getUsers to refresh cache and attach notifications.
- Enhanced DataStore::saveUsers to persist users and notifications.
- Marked modified records in changePassword and saved changes.
- Included DataStoreLockGuard.h in project files.
- Improved error handling for invalid user IDs and missing users.
Related work items: #1929, #1951, #1952
User Story #1953
User Story #1954
**Changes**
- Refactored Notification model to use SerializedNotification for shared memory persistence.
- Removed notification ownership from the User model and stored notifications separately in the DataStore.
- Added notification state tracking to support soft deletion.
- Updated notification creation, retrieval, and deletion flows to use DataStore-managed notifications.
- Refactored observer persistence for Service, Payment, and Inventory Management services to use shared memory mappings.
- Removed file-based observer loading and saving logic.
- Updated notification services to persist notifications directly through the DataStore.
- Added observer load/save support in DataStore.
- Removed legacy FileManager and file-based notification persistence utilities.
- Simplified observer interfaces and removed unused observer ID persistence methods.
- Updated application startup and shutdown flow to use DataStore initialization and cleanup.
Related work items: #1953, #1954
<UserStory> 1954: Implement Service Refactoring </UserStory>
UserStory #1954
<Changes>
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.
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar, please review
</Review>
<UserStory> 1953: Model Refactoring </UserStory>
UserStory #1953
<Changes>
1. Replaced CSV-based Notification serialization and deserialization with SerializedNotification record-based serialization for shared memory storage.
2. Implemented Notification::serialize() to convert Notification objects into fixed-size SerializedNotification structures.
3. Implemented Notification::deserialize() to reconstruct Notification objects directly from SerializedNotification records.
4. Added Notification state persistence by introducing util::State support in constructors, serialization, and deserialization flows.
5. Updated Notification class interfaces to use SerializedNotification types instead of std::string serialization APIs.
6. Removed legacy CSV serialization support, including CSV parsing logic and header generation functionality.
7. Added SerializedNotification dependencies through SerializedRecords.h inclusion and forward declaration support.
8. Initialized Notification objects with ACTIVE state by default and added state getter/setter APIs.
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar, please review
</Review>
User Story #1959
User Story #1960
**Changes**
- Refactored User serialization/deserialization to use SerializedUser.
- Removed user loading and saving responsibilities from UserManagementService.
- Added DataStoreLockGuard for automatic datastore locking/unlocking.
- Updated user operations to work with tracked records.
- Added persistence support for user creation, updates, notification changes, and user removal.
- Refactored notification handling to use datastore-managed notifications.
- Updated DataStore to load and save users and notifications using shared memory records.
- Reworked application startup and shutdown flow using Controller::initialize() and Controller::shutdown().
- Updated UI flow to use the new initialization and shutdown methods.
- Added required project and shared memory updates to support the refactoring.
Related work items: #1925, #1959, #1960
<UserStory> 1950: Implement Service Refactorings </UserStory>
UserStory #1950
<Changes>
1. Added `DataStoreLockGuard` integration in `PaymentManagementService` methods (`sendPaymentReminders`, `generateInvoice`, `getInvoices`, `completePayment`, `getAllInvoices`, `confirmPayment`) to ensure thread-safe access to the datastore.
2. Implemented record enrichment logic in `DataStore::getInvoices()` to automatically link `Invoice` objects with their corresponding `ServiceBooking` and `InventoryItem` entities during loading, validating relationships and throwing exceptions for invalid references.
3. Refactored invoice persistence by implementing `saveInvoices()` using `saveRecords<Invoice, SerializedInvoice>` to write tracked records directly to shared memory.
4. Updated invoice creation and modification flows:
- `generateInvoice`: Uses `createNewRecord` to insert new invoices into the tracked cache and triggers immediate persistence.
- `completePayment` & `confirmPayment`: Marks records as `MODIFIED` in the `TrackedRecord` state before saving changes.
5. Updated data access patterns across `PaymentManagementService` to use `.data` pointers from `TrackedRecord` objects returned by the datastore, replacing direct pointer access to mapped objects.
6. Added necessary header dependencies including `DataStoreLockGuard.h`, `Invoice.h`, and `SerializedRecords.h` to support locking mechanisms and structured serialization.
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar, please review
</Review>
<UserStory> 1949: Model Refactoring</UserStory>
UserStory #1949
<Changes>
Replaced CSV-based serialization and deserialization in the Invoice model with fixed-size SerializedRecord structures for shared memory storage.
Implemented serialize() method to convert Invoice objects into SerializedInvoice records using direct struct field assignment and strcpy_s for string fields.
Implemented deserialize() method to reconstruct Invoice objects directly from SerializedInvoice types instead of parsing CSV strings.
Updated Invoice class interfaces to use SerializedInvoice types, removing legacy CSV serialization APIs including getHeaders() function.
Added SerializedRecords.h dependency and forward declarations for SerializedInvoice structure in Invoice header.
Minor formatting adjustments in DataStore.cpp (closing brace placement).
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar, please review
</Review>
<UserStory> 1927: Implement Service Refactorings </UserStory>
UserStory #1927
<Changes>
1. Added DataStoreLockGuard integration across ServiceManagementService methods for thread-safe datastore operations.
2. Updated DataStore::getServices(), getComboPackages(), getServiceBookings(), and getJobCards() to enrich records with linked entities (inventory items, services, bookings, technicians).
3. Modified ServiceManagementService::purchaseService() and purchaseComboPackage() to use tracked records and persist bookings safely.
4. Enhanced restoreInventory() and processBookingCancellation() to handle tracked records, update record states, and restore inventory items correctly.
5. Refactored cancelCustomerServiceBookings() and cancelTechnicianJobs() to use tracked records, restore inventory, and persist changes.
6. Updated createComboPackage(), removeComboPackage(), and createJobCard() to use tracked records and save changes to datastore.
7. Updated createService() to validate inventory items with tracked records and persist new services safely.
8. Added required header dependencies for DataStoreLockGuard and shared memory support.
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar, please review
</Review>
<UserStory> 1958: Service Refactoring </UserStory>
UserStory #1958
<Changes>
1. Added DataStoreLockGuard.h include to project file and InventoryManagementService
for thread-safe datastore operations.
2. Enhanced DataStore::getUsers to load SerializedUser records, refresh cache,
and attach notifications with recipient validation.
3. Enhanced DataStore::getInventoryItems to load SerializedInventoryItem records
and refresh cache for tracked inventory items.
4. Refactored InventoryManagementService::sendLowStockAlerts to use tracked
inventory and user maps with DataStoreLockGuard, ensuring safe access.
5. Removed legacy observer management, load/save inventory items, and related
persistence functions from InventoryManagementService.
6. Updated InventoryManagementService::addInventoryItem to insert new records
into tracked inventory map and persist changes via saveInventoryItems.
7. Updated InventoryManagementService::addInventoryItemStock to validate item
existence, update quantity, mark record as MODIFIED, and persist changes.
8. Refactored InventoryManagementService::getInventoryItems to return object
map extracted from tracked records with DataStoreLockGuard.
9. Updated InventoryManagementService::removeInventoryItem to validate item ID,
mark state as INACTIVE, set record state to MODIFIED, and persist changes.
10. Updated InventoryManagementService::getInventoryItem to safely retrieve
inventory items from tracked records with error handling.
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar
</Review>
<UserStory> 1957: Model Refactoring </UserStory>
UserStory #1957
<Changes>
1. Added SerializedRecords.h dependency and forward declaration for SerializedInventoryItem
to support fixed-size record storage.
2. Replaced CSV-based serialization in InventoryItem with serialize() method returning
SerializedInventoryItem structure.
3. Replaced CSV-based deserialization logic with deserialize() method that reconstructs
InventoryItem directly from SerializedInventoryItem record.
4. Removed legacy CSV parsing, header generation, and exception handling tied to string-based
serialization.
5. Updated InventoryItem class interface in InventoryItem.h to use SerializedInventoryItem
types instead of std::string serialization APIs.
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar
</Review>
<UserStory> 1952: Service Refactoring </UserStory>
UserStory #1952
<Changes>
1. Enhanced DataStore::getUsers to load SerializedUser records, refresh cache,
and attach notifications to recipient users with validation for recipient IDs.
2. Updated DataStore::saveUsers to persist SerializedUser records and save
notifications alongside user data.
3. Refactored AuthenticationManagementService::login to use DataStoreLockGuard
and tracked user map with SerializedUser-backed records.
4. Modified AuthenticationManagementService::changePassword to ensure thread-safe
updates, mark user record as MODIFIED, and persist changes via DataStore::saveUsers.
5. Added dependencies for Utility.h and DataStoreLockGuard.h in
AuthenticationManagementService.cpp to support safe record handling.
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar
</Review>
<UserStory> 1960: Service Refactoring </UserStory>
UserStory #1960
<Changes>
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.
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar, please review
</Review>
<UserStory> 1951: Model Refactoring</UserStory>
UserStory #1951
<Changes>
1. Replaced CSV-based serialization and deserialization in ComboPackage,
JobCard, Service, and ServiceBooking models with fixed-size SerializedRecord
structures for shared memory storage.
2. Implemented serialize() methods to convert objects into SerializedComboPackage,
SerializedJobCard, SerializedService, and SerializedServiceBooking records.
3. Implemented deserialize() methods to reconstruct objects directly from
SerializedRecord types instead of parsing CSV strings.
4. Updated model class interfaces to use SerializedRecord types, removing
legacy CSV serialization APIs and header generation functions.
5. Added SerializedRecords.h dependencies and forward declarations for
Serialized structures across affected models.
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar
</Review>
<UserStory> 1955: Model Refactoring</UserStory>
UserStory #1955
<Changes>
1. Replaced CSV-based serialization and deserialization in ComboPackage, JobCard, Service, and ServiceBooking models with fixed-size SerializedRecord structures for shared memory storage.
2. Implemented serialize() methods to convert objects into SerializedComboPackage, SerializedJobCard, SerializedService, and SerializedServiceBooking records.
3. Implemented deserialize() methods to reconstruct objects directly from SerializedRecord types instead of parsing CSV strings.
4. Updated model class interfaces to use SerializedRecord types, removing legacy CSV serialization APIs and header generation functions.
5. Added SerializedRecords.h dependencies and forward declarations for Serialized structures across affected models.
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar, please review
</Review>
<UserStory> 1959: Model Refactoring </UserStory>
UserStory #1959
<Changes>
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.
</Changes>
<Test>
N/A
</Test>
<Review>
Sreeja Reghukumar, please review
</Review>
Fix Duplicate Customer Notification Sent When Assigned Technician Is Removed
- Refactored processBookingCancellation to simplify parameters and remove redundant notification arguments.
- Added util::UserType parameter to differentiate cancellation flows for CUSTOMER vs TECHNICIAN.
- Updated cancelCustomerServiceBookings to use processBookingCancellation with util::UserType::CUSTOMER.
- Updated cancelTechnicianJobs to use processBookingCancellation with util::UserType::TECHNICIAN.
- Enhanced booking status handling by including IN_PROGRESS status in cancellation checks.
- Ensured job cards are consistently marked CANCELLED and inventory restored.
- Fixed duplicate notification issue where customers received multiple alerts when technician was removed.
Fixes#1807
Related work items: #1807