Create a SQL Server user specifically for shopMaster with minimal required permissions.
1
Create the login
CREATE LOGIN shopmaster_sync WITH PASSWORD = 'YourSecurePassword123!';
Use a strong password with at least 12 characters, including uppercase, lowercase, numbers, and symbols.
2
Create database user
USE YourDatabaseName;GOCREATE USER shopmaster_sync FOR LOGIN shopmaster_sync;GO
3
Grant minimum permissions
-- Permissions on product tableGRANT SELECT, INSERT, UPDATE, DELETE ON dbo.YourProductTable TO shopmaster_sync;-- Permissions for ChangeLog tableGRANT SELECT, INSERT, DELETE ON dbo.ChangeLog TO shopmaster_sync;-- One-time permissions for initial configurationGRANT CREATE TABLE TO shopmaster_sync;GRANT ALTER ON SCHEMA::dbo TO shopmaster_sync;
4
Revoke configuration permissions after setup
After running Configure successfully, remove unnecessary permissions:
REVOKE CREATE TABLE FROM shopmaster_sync;REVOKE ALTER ON SCHEMA::dbo FROM shopmaster_sync;
Ensure your product table is properly indexed for fast trigger execution.
Create a primary key on ProductID
The ProductID column should be the primary key:
ALTER TABLE YourProductTableADD CONSTRAINT PK_ProductID PRIMARY KEY (ProductID);
This ensures:
Fast lookups during sync
Data integrity (no duplicate products)
Optimal trigger performance
Index frequently filtered columns
If you plan to extend shopMaster to filter by Status or other fields:
CREATE INDEX IX_ProductStatus ON YourProductTable(Status)WHERE Status = 1; -- Active products only
Keep the table clean
Regularly archive or delete obsolete products:
-- Archive old deleted productsINSERT INTO ProductArchiveSELECT * FROM YourProductTableWHERE Status = 0 AND ModifiedDate < DATEADD(YEAR, -1, GETDATE());DELETE FROM YourProductTableWHERE Status = 0 AND ModifiedDate < DATEADD(YEAR, -1, GETDATE());
The ChangeLog table can grow large if syncs fail repeatedly.
1
Set up monitoring
Check ChangeLog size regularly:
SELECT COUNT(*) AS TotalRecords, MIN(ChangeDateTime) AS OldestChange, MAX(ChangeDateTime) AS NewestChangeFROM ChangeLog;
2
Create an alert for excessive growth
-- Create a view for monitoringCREATE VIEW vw_ChangeLogHealth ASSELECT COUNT(*) AS RecordCount, DATEDIFF(HOUR, MIN(ChangeDateTime), GETDATE()) AS OldestChangeHours, CASE WHEN COUNT(*) > 10000 THEN 'WARNING: High record count' WHEN DATEDIFF(HOUR, MIN(ChangeDateTime), GETDATE()) > 48 THEN 'WARNING: Old changes not synced' ELSE 'OK' END AS HealthStatusFROM ChangeLog;
3
Manual cleanup if needed
If sync fails and you need to clear the backlog:
-- Backup firstSELECT * INTO ChangeLog_Backup_20260303 FROM ChangeLog;-- Clear specific date rangeDELETE FROM ChangeLog WHERE ChangeDateTime < '2026-03-01';
Only delete ChangeLog records if you’re certain those changes have been synced or are no longer needed.
SQL Server uses statistics to optimize queries. Keep them current:
-- Update statistics on product tableUPDATE STATISTICS YourProductTable WITH FULLSCAN;-- Update statistics on ChangeLogUPDATE STATISTICS ChangeLog WITH FULLSCAN;
Consider scheduling this as a SQL Server Agent job every Sunday at 2 AM.
2
Rebuild indexes monthly
Fragmented indexes slow down trigger execution:
-- Rebuild all indexes on product tableALTER INDEX ALL ON YourProductTable REBUILD;-- Or reorganize if rebuild takes too longALTER INDEX ALL ON YourProductTable REORGANIZE;
3
Monitor trigger performance
Check how long triggers take to execute:
-- Enable statisticsSET STATISTICS TIME ON;SET STATISTICS IO ON;-- Test an updateUPDATE YourProductTableSET SellPrice = SellPriceWHERE ProductID = 'TEST001';-- Check ChangeLog was updatedSELECT * FROM ChangeLog WHERE ProductID = 'TEST001';
Triggers should complete in under 10ms. If slower, investigate indexing.
4
Archive old ChangeLog records
Even though ChangeLog is cleared after sync, occasional failures can cause buildup:
-- Create archive table (one-time)SELECT TOP 0 * INTO ChangeLog_Archive FROM ChangeLog;-- Monthly: Archive records older than 7 daysINSERT INTO ChangeLog_ArchiveSELECT * FROM ChangeLogWHERE ChangeDateTime < DATEADD(DAY, -7, GETDATE());DELETE FROM ChangeLogWHERE ChangeDateTime < DATEADD(DAY, -7, GETDATE());
Implement monitoring to catch issues before they become problems.
1
Create a sync health check query
CREATE VIEW vw_SyncHealth ASSELECT (SELECT COUNT(*) FROM ChangeLog) AS PendingChanges, (SELECT MAX(ChangeDateTime) FROM ChangeLog) AS OldestPendingChange, CASE WHEN (SELECT COUNT(*) FROM ChangeLog) > 1000 THEN 'CRITICAL' WHEN (SELECT COUNT(*) FROM ChangeLog) > 500 THEN 'WARNING' WHEN (SELECT MAX(ChangeDateTime) FROM ChangeLog) < DATEADD(HOUR, -2, GETDATE()) THEN 'WARNING' ELSE 'HEALTHY' END AS HealthStatus, CASE WHEN (SELECT COUNT(*) FROM ChangeLog) > 1000 THEN 'More than 1000 pending changes - sync may be failing' WHEN (SELECT COUNT(*) FROM ChangeLog) > 500 THEN 'High number of pending changes' WHEN (SELECT MAX(ChangeDateTime) FROM ChangeLog) < DATEADD(HOUR, -2, GETDATE()) THEN 'Changes older than 2 hours not synced' ELSE 'All systems operational' END AS StatusMessage;
Your .env file contains critical configuration. Back it up securely:Automated backup script (PowerShell):
# Save as backup-shopmaster-config.ps1$sourcePath = "C:\path\to\.env"$backupDir = "C:\Backups\shopMaster"$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"$backupPath = "$backupDir\.env_$timestamp"# Create backup directory if not existsif (!(Test-Path $backupDir)) { New-Item -ItemType Directory -Path $backupDir}# Copy and encryptCopy-Item $sourcePath $backupPath# Keep only last 30 backupsGet-ChildItem $backupDir -Filter ".env_*" | Sort-Object CreationTime -Descending | Select-Object -Skip 30 | Remove-Item
Schedule this with Task Scheduler to run daily.
Backup your SQL Server database
Regular database backups protect against data loss:
-- Full backup (weekly)BACKUP DATABASE YourDatabaseNameTO DISK = 'C:\Backups\YourDB_Full.bak'WITH INIT, COMPRESSION;-- Differential backup (daily)BACKUP DATABASE YourDatabaseNameTO DISK = 'C:\Backups\YourDB_Diff.bak'WITH DIFFERENTIAL, INIT, COMPRESSION;
Schedule these as SQL Server Agent jobs.
Test your backups
Monthly: Restore a backup to a test database and verify:
Product table structure is intact
ChangeLog table exists
Triggers are present and enabled
Data is complete and accurate
-- Restore to test databaseRESTORE DATABASE YourDB_TestFROM DISK = 'C:\Backups\YourDB_Full.bak'WITH MOVE 'YourDB' TO 'C:\Data\YourDB_Test.mdf', MOVE 'YourDB_Log' TO 'C:\Data\YourDB_Test_Log.ldf', REPLACE;-- VerifyUSE YourDB_Test;SELECT COUNT(*) FROM YourProductTable;SELECT name FROM sys.triggers WHERE parent_id = OBJECT_ID('YourProductTable');