Log employee and Trace offline sync and navigation events

Adds cache sync start, skip, success, and failure logs for employee RFID and meal/menu refreshes.

Logs full offline cache sync flow and meal schedule screen navigation.
feature/centralized-offline-canteen
SYED MUSTUFA AHMED NAQVI 2026-06-01 15:18:01 +05:00
parent 3df4bc2672
commit 55e75b7347
4 changed files with 31 additions and 0 deletions

View File

@ -2,6 +2,7 @@ using Microsoft.EntityFrameworkCore;
using MySqlConnector; using MySqlConnector;
using UtopiaCanteenSystem.Data; using UtopiaCanteenSystem.Data;
using UtopiaCanteenSystem.Models; using UtopiaCanteenSystem.Models;
using UtopiaCanteenSystem.Services.Logging;
namespace UtopiaCanteenSystem.Services; namespace UtopiaCanteenSystem.Services;
@ -22,9 +23,12 @@ public class EmployeeRfidTagSyncService : IEmployeeRfidTagSyncService
public async Task<EmployeeRfidTagSyncResult> SyncAllAsync(CancellationToken cancellationToken = default) public async Task<EmployeeRfidTagSyncResult> SyncAllAsync(CancellationToken cancellationToken = default)
{ {
FileLogger.Info("CacheSync", "Employee RFID sync started.");
var connectionString = _configService.GetHrmsLookupConnectionString(); var connectionString = _configService.GetHrmsLookupConnectionString();
if (string.IsNullOrWhiteSpace(connectionString)) if (string.IsNullOrWhiteSpace(connectionString))
{ {
FileLogger.Warn("CacheSync", "Employee RFID sync skipped. MySQL connection string is not configured.");
return new EmployeeRfidTagSyncResult return new EmployeeRfidTagSyncResult
{ {
Success = false, Success = false,
@ -36,10 +40,12 @@ public class EmployeeRfidTagSyncService : IEmployeeRfidTagSyncService
try try
{ {
rows = await FetchAllFromHrmsAsync(connectionString, cancellationToken).ConfigureAwait(false); rows = await FetchAllFromHrmsAsync(connectionString, cancellationToken).ConfigureAwait(false);
FileLogger.Info("CacheSync", $"Employee RFID rows fetched from HRMS/UIND. RowsFetched={rows.Count}.");
} }
catch (Exception ex) catch (Exception ex)
{ {
Logger.Log(ex, "EmployeeRfidTagSyncService.SyncAllAsync"); Logger.Log(ex, "EmployeeRfidTagSyncService.SyncAllAsync");
FileLogger.Error("CacheSync", "Employee RFID sync failed while fetching from HRMS/UIND.", ex);
return new EmployeeRfidTagSyncResult return new EmployeeRfidTagSyncResult
{ {
Success = false, Success = false,
@ -85,6 +91,10 @@ public class EmployeeRfidTagSyncService : IEmployeeRfidTagSyncService
await db.SaveChangesAsync(cancellationToken).ConfigureAwait(false); await db.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
_configService.SetLastEmployeeRfidCacheSyncUtc(syncedAt); _configService.SetLastEmployeeRfidCacheSyncUtc(syncedAt);
FileLogger.Info(
"CacheSync",
$"Employee RFID sync completed. RowsFetched={rows.Count}, Upserted={upserted}.");
return new EmployeeRfidTagSyncResult return new EmployeeRfidTagSyncResult
{ {
Success = true, Success = true,

View File

@ -2,6 +2,7 @@ using Microsoft.EntityFrameworkCore;
using MySqlConnector; using MySqlConnector;
using UtopiaCanteenSystem.Data; using UtopiaCanteenSystem.Data;
using UtopiaCanteenSystem.Models; using UtopiaCanteenSystem.Models;
using UtopiaCanteenSystem.Services.Logging;
namespace UtopiaCanteenSystem.Services; namespace UtopiaCanteenSystem.Services;
@ -21,9 +22,12 @@ public class MealMenuCacheSyncService : IMealMenuCacheSyncService
public async Task<MealMenuCacheSyncResult> SyncAllAsync(CancellationToken cancellationToken = default) public async Task<MealMenuCacheSyncResult> SyncAllAsync(CancellationToken cancellationToken = default)
{ {
FileLogger.Info("CacheSync", "Meal/menu cache sync started.");
var connectionString = _configService.GetHrmsLookupConnectionString(); var connectionString = _configService.GetHrmsLookupConnectionString();
if (string.IsNullOrWhiteSpace(connectionString)) if (string.IsNullOrWhiteSpace(connectionString))
{ {
FileLogger.Warn("CacheSync", "Meal/menu sync skipped. MySQL connection string is not configured.");
return new MealMenuCacheSyncResult return new MealMenuCacheSyncResult
{ {
Success = false, Success = false,
@ -49,6 +53,11 @@ public class MealMenuCacheSyncService : IMealMenuCacheSyncService
await db.SaveChangesAsync(cancellationToken).ConfigureAwait(false); await db.SaveChangesAsync(cancellationToken).ConfigureAwait(false);
_configService.SetLastMealMenuCacheSyncUtc(syncedAt); _configService.SetLastMealMenuCacheSyncUtc(syncedAt);
FileLogger.Info(
"CacheSync",
$"Meal/menu sync completed. MealSchedules={mealScheduleCount}, MenuWeeks={lunchWeekCount}, " +
$"MenuItems={lunchItemCount}, CatalogItems={menuItemCount}.");
return new MealMenuCacheSyncResult return new MealMenuCacheSyncResult
{ {
Success = true, Success = true,
@ -61,6 +70,7 @@ public class MealMenuCacheSyncService : IMealMenuCacheSyncService
catch (Exception ex) catch (Exception ex)
{ {
Logger.Log(ex, "MealMenuCacheSyncService.SyncAllAsync"); Logger.Log(ex, "MealMenuCacheSyncService.SyncAllAsync");
FileLogger.Error("CacheSync", $"Meal/menu sync failed. Error={ex.Message}", ex);
return new MealMenuCacheSyncResult return new MealMenuCacheSyncResult
{ {
Success = false, Success = false,

View File

@ -1,5 +1,7 @@
using UtopiaCanteenSystem.ViewModels; using UtopiaCanteenSystem.ViewModels;
using UtopiaCanteenSystem.Services.Logging;
namespace UtopiaCanteenSystem.Services; namespace UtopiaCanteenSystem.Services;
/// <summary> /// <summary>
@ -105,6 +107,7 @@ public class NavigationService : INavigationService
NavigateToAdminLogin(); NavigateToAdminLogin();
return; return;
} }
FileLogger.Info("ClientNav", "Meal Schedules screen opened.");
CurrentViewModel = _mealSchedulesVm(); CurrentViewModel = _mealSchedulesVm();
} }

View File

@ -1,3 +1,5 @@
using UtopiaCanteenSystem.Services.Logging;
namespace UtopiaCanteenSystem.Services; namespace UtopiaCanteenSystem.Services;
public class OfflineCacheSyncService : IOfflineCacheSyncService public class OfflineCacheSyncService : IOfflineCacheSyncService
@ -15,9 +17,12 @@ public class OfflineCacheSyncService : IOfflineCacheSyncService
public async Task<OfflineCacheSyncResult> SyncEmployeeAndMenuCacheAsync(CancellationToken cancellationToken = default) public async Task<OfflineCacheSyncResult> SyncEmployeeAndMenuCacheAsync(CancellationToken cancellationToken = default)
{ {
FileLogger.Info("CacheSync", "Full offline cache sync started (employee RFID + meal/menu).");
var employeeResult = await _employeeRfidTagSync.SyncAllAsync(cancellationToken).ConfigureAwait(false); var employeeResult = await _employeeRfidTagSync.SyncAllAsync(cancellationToken).ConfigureAwait(false);
if (!employeeResult.Success) if (!employeeResult.Success)
{ {
FileLogger.Error("CacheSync", $"Full cache sync failed at employee RFID step. Error={employeeResult.ErrorMessage}");
return new OfflineCacheSyncResult return new OfflineCacheSyncResult
{ {
Success = false, Success = false,
@ -29,6 +34,7 @@ public class OfflineCacheSyncService : IOfflineCacheSyncService
var mealMenuResult = await _mealMenuCacheSync.SyncAllAsync(cancellationToken).ConfigureAwait(false); var mealMenuResult = await _mealMenuCacheSync.SyncAllAsync(cancellationToken).ConfigureAwait(false);
if (!mealMenuResult.Success) if (!mealMenuResult.Success)
{ {
FileLogger.Error("CacheSync", $"Full cache sync failed at meal/menu step. Error={mealMenuResult.ErrorMessage}");
return new OfflineCacheSyncResult return new OfflineCacheSyncResult
{ {
Success = false, Success = false,
@ -38,6 +44,8 @@ public class OfflineCacheSyncService : IOfflineCacheSyncService
}; };
} }
FileLogger.Info("CacheSync", "Full offline cache sync completed successfully.");
return new OfflineCacheSyncResult return new OfflineCacheSyncResult
{ {
Success = true, Success = true,