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
parent
7b2b9b353e
commit
c659bbaa86
|
|
@ -1,6 +1,9 @@
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using CommunityToolkit.Mvvm.Input;
|
using CommunityToolkit.Mvvm.Input;
|
||||||
using UtopiaCanteenSystem.Services;
|
using UtopiaCanteenSystem.Services;
|
||||||
|
using UtopiaCanteenSystem.Services.Logging;
|
||||||
|
|
||||||
namespace UtopiaCanteen.Client.ViewModels;
|
namespace UtopiaCanteen.Client.ViewModels;
|
||||||
|
|
||||||
|
|
@ -219,6 +222,9 @@ public partial class ClientSettingsViewModel : ObservableObject
|
||||||
_configService.SetScanIntervalMinutes(minutes);
|
_configService.SetScanIntervalMinutes(minutes);
|
||||||
_configService.SetScanIntervalSeconds(seconds);
|
_configService.SetScanIntervalSeconds(seconds);
|
||||||
_configService.SetAdminCardId(AdminCardId?.Trim() ?? string.Empty);
|
_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.SetCentralServerBaseUrl(BackendBaseUrl.Trim());
|
||||||
_configService.SetDeviceId(DeviceId?.Trim() ?? string.Empty);
|
_configService.SetDeviceId(DeviceId?.Trim() ?? string.Empty);
|
||||||
var site = SiteId?.Trim() ?? string.Empty;
|
var site = SiteId?.Trim() ?? string.Empty;
|
||||||
|
|
@ -243,6 +249,28 @@ public partial class ClientSettingsViewModel : ObservableObject
|
||||||
[RelayCommand]
|
[RelayCommand]
|
||||||
private void OpenMealSchedules() => _navigation.NavigateToMealSchedules();
|
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]
|
[RelayCommand]
|
||||||
private async Task SyncEmployeeAndMenuCacheNow()
|
private async Task SyncEmployeeAndMenuCacheNow()
|
||||||
{
|
{
|
||||||
|
|
@ -255,14 +283,21 @@ public partial class ClientSettingsViewModel : ObservableObject
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
FileLogger.Info("ClientSettings", "Sync Now clicked.");
|
||||||
if (!await EnsureBackendAvailableAsync().ConfigureAwait(true))
|
if (!await EnsureBackendAvailableAsync().ConfigureAwait(true))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
var url = $"{_configService.GetBackendBaseUrl().TrimEnd('/')}/api/cache/sync-now";
|
||||||
|
FileLogger.Info("ClientSettings", $"Calling POST {url}");
|
||||||
|
|
||||||
var result = await _backendApi.SyncCacheNowAsync().ConfigureAwait(true);
|
var result = await _backendApi.SyncCacheNowAsync().ConfigureAwait(true);
|
||||||
await RefreshCacheSyncTimestampsAsync().ConfigureAwait(true);
|
await RefreshCacheSyncTimestampsAsync().ConfigureAwait(true);
|
||||||
|
|
||||||
SaveMessage = result.Message;
|
SaveMessage = result.Message;
|
||||||
IsError = !result.Success;
|
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)
|
if (!string.IsNullOrWhiteSpace(result.Details) && result.Success)
|
||||||
SaveMessage += " " + result.Details;
|
SaveMessage += " " + result.Details;
|
||||||
}
|
}
|
||||||
|
|
@ -290,12 +325,19 @@ public partial class ClientSettingsViewModel : ObservableObject
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
FileLogger.Info("ClientSettings", "Post Data clicked.");
|
||||||
if (!await EnsureBackendAvailableAsync().ConfigureAwait(true))
|
if (!await EnsureBackendAvailableAsync().ConfigureAwait(true))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
var url = $"{_configService.GetBackendBaseUrl().TrimEnd('/')}/api/orders/sync-now";
|
||||||
|
FileLogger.Info("ClientSettings", $"Calling POST {url}");
|
||||||
|
|
||||||
var result = await _backendApi.SyncOrdersNowAsync().ConfigureAwait(true);
|
var result = await _backendApi.SyncOrdersNowAsync().ConfigureAwait(true);
|
||||||
SaveMessage = result.Message;
|
SaveMessage = result.Message;
|
||||||
IsError = !result.Success;
|
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)
|
if (!string.IsNullOrWhiteSpace(result.Details) && result.Success)
|
||||||
SaveMessage += " " + result.Details;
|
SaveMessage += " " + result.Details;
|
||||||
}
|
}
|
||||||
|
|
@ -326,6 +368,7 @@ public partial class ClientSettingsViewModel : ObservableObject
|
||||||
|
|
||||||
SaveMessage = BackendUnavailableMessage;
|
SaveMessage = BackendUnavailableMessage;
|
||||||
IsError = true;
|
IsError = true;
|
||||||
|
FileLogger.Warn("ClientSettings", $"Backend unavailable. Url={_configService.GetBackendBaseUrl()}");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -246,6 +246,7 @@ using CommunityToolkit.Mvvm.Input;
|
||||||
using MySqlConnector;
|
using MySqlConnector;
|
||||||
using UtopiaCanteenSystem.Models;
|
using UtopiaCanteenSystem.Models;
|
||||||
using UtopiaCanteenSystem.Services;
|
using UtopiaCanteenSystem.Services;
|
||||||
|
using UtopiaCanteenSystem.Services.Logging;
|
||||||
|
|
||||||
namespace UtopiaCanteenSystem.ViewModels;
|
namespace UtopiaCanteenSystem.ViewModels;
|
||||||
|
|
||||||
|
|
@ -289,6 +290,7 @@ public partial class MealSchedulesViewModel : ObservableObject
|
||||||
_navigation = navigation;
|
_navigation = navigation;
|
||||||
_configService = configService;
|
_configService = configService;
|
||||||
_currentSiteId = (_configService.GetSiteId() ?? string.Empty).Trim();
|
_currentSiteId = (_configService.GetSiteId() ?? string.Empty).Trim();
|
||||||
|
FileLogger.Info("MealSchedules", "Meal Schedules view opened; loading schedules from backend.");
|
||||||
_ = LoadSchedulesAsync();
|
_ = LoadSchedulesAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -352,6 +354,7 @@ public partial class MealSchedulesViewModel : ObservableObject
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
IsError = true;
|
IsError = true;
|
||||||
|
FileLogger.Error("MealSchedules", "Could not load schedules from backend.", ex);
|
||||||
|
|
||||||
var msg = ex is MySqlException mysql
|
var msg = ex is MySqlException mysql
|
||||||
? $"{mysql.Message}{Environment.NewLine}{Environment.NewLine}{mysql.StackTrace}"
|
? $"{mysql.Message}{Environment.NewLine}{Environment.NewLine}{mysql.StackTrace}"
|
||||||
|
|
|
||||||
|
|
@ -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."
|
||||||
Loading…
Reference in New Issue