Log meal schedule loading and add clean helper

Logs meal schedule load failures and adds a build cleanup helper for locked build artifacts.
feature/centralized-offline-canteen
SYED MUSTUFA AHMED NAQVI 2026-06-01 15:24:33 +05:00
parent 7b2b9b353e
commit c659bbaa86
3 changed files with 86 additions and 0 deletions

View File

@ -1,6 +1,9 @@
using System.Diagnostics;
using System.IO;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using UtopiaCanteenSystem.Services;
using UtopiaCanteenSystem.Services.Logging;
namespace UtopiaCanteen.Client.ViewModels;
@ -219,6 +222,9 @@ public partial class ClientSettingsViewModel : ObservableObject
_configService.SetScanIntervalMinutes(minutes);
_configService.SetScanIntervalSeconds(seconds);
_configService.SetAdminCardId(AdminCardId?.Trim() ?? string.Empty);
FileLogger.Info(
"ClientSettings",
$"Settings saved. AdminCardId={AdminCardId?.Trim()}, SiteId={SiteId?.Trim()}, DeviceId={DeviceId?.Trim()}");
_configService.SetCentralServerBaseUrl(BackendBaseUrl.Trim());
_configService.SetDeviceId(DeviceId?.Trim() ?? string.Empty);
var site = SiteId?.Trim() ?? string.Empty;
@ -243,6 +249,28 @@ public partial class ClientSettingsViewModel : ObservableObject
[RelayCommand]
private void OpenMealSchedules() => _navigation.NavigateToMealSchedules();
[RelayCommand]
private void OpenLogsFolder()
{
try
{
var dir = LogPaths.ClientLogsDirectory;
Directory.CreateDirectory(dir);
Process.Start(new ProcessStartInfo
{
FileName = dir,
UseShellExecute = true
});
FileLogger.Info("ClientSettings", $"Opened logs folder: {dir}");
}
catch (Exception ex)
{
FileLogger.Error("ClientSettings", "Failed to open logs folder.", ex);
SaveMessage = "Could not open logs folder: " + ex.Message;
IsError = true;
}
}
[RelayCommand]
private async Task SyncEmployeeAndMenuCacheNow()
{
@ -255,14 +283,21 @@ public partial class ClientSettingsViewModel : ObservableObject
try
{
FileLogger.Info("ClientSettings", "Sync Now clicked.");
if (!await EnsureBackendAvailableAsync().ConfigureAwait(true))
return;
var url = $"{_configService.GetBackendBaseUrl().TrimEnd('/')}/api/cache/sync-now";
FileLogger.Info("ClientSettings", $"Calling POST {url}");
var result = await _backendApi.SyncCacheNowAsync().ConfigureAwait(true);
await RefreshCacheSyncTimestampsAsync().ConfigureAwait(true);
SaveMessage = result.Message;
IsError = !result.Success;
FileLogger.Info(
"ClientSettings",
$"Sync Now response. Success={result.Success}, Message={result.Message}, Details={result.Details}");
if (!string.IsNullOrWhiteSpace(result.Details) && result.Success)
SaveMessage += " " + result.Details;
}
@ -290,12 +325,19 @@ public partial class ClientSettingsViewModel : ObservableObject
try
{
FileLogger.Info("ClientSettings", "Post Data clicked.");
if (!await EnsureBackendAvailableAsync().ConfigureAwait(true))
return;
var url = $"{_configService.GetBackendBaseUrl().TrimEnd('/')}/api/orders/sync-now";
FileLogger.Info("ClientSettings", $"Calling POST {url}");
var result = await _backendApi.SyncOrdersNowAsync().ConfigureAwait(true);
SaveMessage = result.Message;
IsError = !result.Success;
FileLogger.Info(
"ClientSettings",
$"Post Data response. Success={result.Success}, Message={result.Message}, Details={result.Details}");
if (!string.IsNullOrWhiteSpace(result.Details) && result.Success)
SaveMessage += " " + result.Details;
}
@ -326,6 +368,7 @@ public partial class ClientSettingsViewModel : ObservableObject
SaveMessage = BackendUnavailableMessage;
IsError = true;
FileLogger.Warn("ClientSettings", $"Backend unavailable. Url={_configService.GetBackendBaseUrl()}");
return false;
}

View File

@ -246,6 +246,7 @@ using CommunityToolkit.Mvvm.Input;
using MySqlConnector;
using UtopiaCanteenSystem.Models;
using UtopiaCanteenSystem.Services;
using UtopiaCanteenSystem.Services.Logging;
namespace UtopiaCanteenSystem.ViewModels;
@ -289,6 +290,7 @@ public partial class MealSchedulesViewModel : ObservableObject
_navigation = navigation;
_configService = configService;
_currentSiteId = (_configService.GetSiteId() ?? string.Empty).Trim();
FileLogger.Info("MealSchedules", "Meal Schedules view opened; loading schedules from backend.");
_ = LoadSchedulesAsync();
}
@ -352,6 +354,7 @@ public partial class MealSchedulesViewModel : ObservableObject
catch (Exception ex)
{
IsError = true;
FileLogger.Error("MealSchedules", "Could not load schedules from backend.", ex);
var msg = ex is MySqlException mysql
? $"{mysql.Message}{Environment.NewLine}{Environment.NewLine}{mysql.StackTrace}"

40
scripts/clean-build.ps1 Normal file
View File

@ -0,0 +1,40 @@
$ErrorActionPreference = "Continue"
Write-Host "Stopping .NET build servers..."
dotnet build-server shutdown
Write-Host "Killing running app/dotnet processes..."
taskkill /F /IM dotnet.exe 2>$null
taskkill /F /IM UtopiaCanteen.Client.exe 2>$null
taskkill /F /IM UtopiaCanteen.BackendService.exe 2>$null
taskkill /F /IM UtopiaCanteenSystem.exe 2>$null
$root = Split-Path -Parent $PSScriptRoot
Set-Location $root
$me = "$env:USERDOMAIN\$env:USERNAME"
$targets = @(
"obj",
"bin",
"UtopiaCanteen.BackendService\obj",
"UtopiaCanteen.BackendService\bin",
"UtopiaCanteen.Client\obj",
"UtopiaCanteen.Client\bin",
"UtopiaCanteen.Backend\obj",
"UtopiaCanteen.Backend\bin",
"UtopiaCanteen.Shared\obj",
"UtopiaCanteen.Shared\bin"
)
foreach ($t in $targets) {
if (Test-Path $t) {
Write-Host "Taking ownership and removing: $t"
takeown /F $t /R /D Y | Out-Null
icacls $t /grant "${me}:(OI)(CI)F" /T /C | Out-Null
attrib -R $t /S /D
Remove-Item -LiteralPath $t -Recurse -Force -ErrorAction SilentlyContinue
}
}
Write-Host "Clean complete."