Menu Sync Implementation
Menu sync Implementation
1. Preface
- Before implementing this approach, it is important to follow certain rules.
- To ensure data correctness, we need to use transactions when updating the database.
- Because Record ID might match went we storage it in Central Database. So the primary key will be the pair key (RecordID, StoreID)
- This implementation uses the merging data approach, where we combine the data from the local and server sources based on the Record ID and Record UpdatedAt criteria.
- On Cloud we will remove all foreign keys for tables (because we using pair primary key [ID, StoreID] so using foreign key constrant might strict some correct record inserted)
2. Data Center Endpoints
- Supported tables:
"autoSendMesssage"
"bulkDetails"
"bulks"
"buttonInfo"
"forceModifierTemplates"
"initParams"
"itemDepartmentModifiers"
"itemGroups"
"itemCategories"
"items"
"itemKitchenDetails"
"itemLocations"
"itemPriceLevels"
"itemStoreDetails"
"itemTimePrices"
"itemTypes"
"itemVendorDetails"
"modifiers"
"modifierGroups"
"purchaseOrderDetails"
"purchaseOrders"
"saleTypes"
"specialItems"
"stores"
"taxAuthorities"
"taxCodeDetails"
"taxCodes"
"timePriceDetails"
"timePrices"
"vendors"
"auditImages"
"GlobalPriceLevels"
"ItemKDSDetails"
"KDSPrinter"
"Kitchens"
"LabelPrinter"
"ServiceCharge"
Sync Menu Endpoint Usages
- URL: {{host}}/api/menus/sync
- HEADER: Method: POST, Content-Type: multipart/form-data
lastSyncDate
: Last time the POS server syncedstoreID
: ID of the storeother properties
: The key represents the table name, and the value is an array of all changed data since the lastSyncDate.imageFiles
: List of files
- Response:
Body Contents:
// Request
{
"lastSyncDate": "2023-06-21T16:52:42.8865722+07:00",
"storeID": "11111",
"autoSendMesssage": [],
"bulkDetails": null,
"bulks": null,
"buttonInfo": null,
"forceModifierTemplates": null,
"initParams": null,
"itemDepartmentModifiers": null,
"itemGroups": null,
"itemCategories": null,
"items": null,
"itemKitchenDetails": null,
"itemLocations": null,
"itemPriceLevels": null,
"itemStoreDetails": null,
"itemTimePrices": null,
"itemTypes": null,
"itemVendorDetails": null,
"modifiers": null,
"modifierGroups": null,
"purchaseOrderDetails": null,
"purchaseOrders": null,
"saleTypes": null,
"specialItems": null,
"stores": null,
"taxAuthorities": null,
"taxCodeDetails": null,
"taxCodes": null,
"timePriceDetails": null,
"timePrices": null,
"vendors": null,
"auditImages": null,
"imageFiles": null
}
// Response
{
"lastSyncDate": "2023-06-21T16:52:42.8865722+07:00",
"storeID": "11111",
"autoSendMesssage": [],
"bulkDetails": null,
"bulks": null,
"buttonInfo": null,
"forceModifierTemplates": null,
"initParams": null,
"itemDepartmentModifiers": null,
"itemGroups": null,
"itemCategories": null,
"items": null,
"itemKitchenDetails": null,
"itemLocations": null,
"itemPriceLevels": null,
"itemStoreDetails": null,
"itemTimePrices": null,
"itemTypes": null,
"itemVendorDetails": null,
"modifiers": null,
"modifierGroups": null,
"purchaseOrderDetails": null,
"purchaseOrders": null,
"saleTypes": null,
"specialItems": null,
"stores": null,
"taxAuthorities": null,
"taxCodeDetails": null,
"taxCodes": null,
"timePriceDetails": null,
"timePrices": null,
"vendors": null,
"auditImages" : null
}
lastSyncDate
: Time Server finish syncstoreID
: ID of the storeother properties
: The key represents the table name, and the value is an array of the merged list.
3. Workflow
Overview of the workflow - The POS server must persistently save the LastSyncDate
field, which represents the last time we synced. - The POS server sends the records that have been updated/created since the last sync. - The Data Center compares the received list with its local database to determine which records are newly created and which ones are updated. - The Data Center queries the records that have been updated/created since the last sync. - Finally, the Data Center merges the two lists (the list changed from the POS and the list changed from the Data Center) into one, considering only the latest changes. - The merged list will be filter to get update records List from server - The update records List from server is then sent back to the POS server. - The POS server takes the update records and updates its database accordingly. - The POS server update LastSyncDate

## 4. Scalability This scalability is applicable to the Data Center Sync endpoint. - Adding new tables to sync is straightforward if you follow a few steps: - Add a new table to the database, (Note add StoreID as Primary key). - Create an entity class. Example C# [Table("[pos].[ItemTypes]")] [PrimaryKeyAttribute(Key = "ItemTypeCode")] public class ItemTypeEntity : IMenuComponent { [ExplicitKey] public string ItemTypeCode { get; set; } [ExplicitKey] public string StoreID { get; set; } public string ItemTypeName { get; set; } public string Description { get; set; } public DateTime UpdatedAt { get; set; } public bool IsDeleted { get; set; } }
- Add the new table and entity class to the syncOrder
Collection in the SyncService class. Note that the new table should follow the sync order since a relational database is used. - Add the table property in Menu_Sync_Request
. Follow the convention of making the property’s key the same as the table name. - Run and test the result.
5. Testing
This section describes the ways to test the Sync endpoint: - Postman is used to test this endpoint. You can check out some predefined cases in this file (please import it into your postman) - Some seeder endpoints have also been created to assist in testing. - After importing, your Postman should appear as shown in the following screenshot:

Cases I’ve tested:
Case: Sync 35 tables (Full table)
Descriptions: - Sync up means pushing the changes to the server. - Sync down means pulling the changes from the server. 1. Sync up Create Full table - Call 5/ Sync Up All Created
2. Sync up Update Full table - Call 6/ Sync Up All Updated
3. Sync down Create Full table - Call Seeder/5_Create ALL Entities
- Call 3/ Sync Down All Created
4. Sync down Update Full table - Call Seeder/6_Update ALL Entities
- Call 4/ Sync Down All Updated
5. Sync up + down Create - Call Seeder/5_Create ALL Entities
- Call 6/ Sync Up + Down All Created
6. Sync up + down Update - Call Seeder/6_Update ALL Entities
- Call 6/ Sync Up + Down All Updated