From 8d4a46206ba82e3bd120a26d1194f51542a4ace1 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 27 Aug 2025 19:52:04 +0000 Subject: [PATCH] Implement external configuration file persistence for Docker containers Co-authored-by: clayschaad <11883505+clayschaad@users.noreply.github.com> --- Server/config/shifts.json | 44 +++++++++++++++ Server/config/transport.json | 10 ++++ Services/ConfigurationService.cs | 93 +++++++++++++++++++++++++++++++- 3 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 Server/config/shifts.json create mode 100644 Server/config/transport.json diff --git a/Server/config/shifts.json b/Server/config/shifts.json new file mode 100644 index 0000000..12a21ed --- /dev/null +++ b/Server/config/shifts.json @@ -0,0 +1,44 @@ +[ + { + "Name": "Frei", + "Icon": "\u26AB", + "MorningTime": "", + "AfternoonTime": "", + "IsPngIcon": false + }, + { + "Name": "Urlaub", + "Icon": "\uD83C\uDF34", + "MorningTime": "", + "AfternoonTime": "", + "IsPngIcon": false + }, + { + "Name": "Pause", + "Icon": "break-icon.png", + "MorningTime": "10:00-10:15", + "AfternoonTime": "15:00-15:15", + "IsPngIcon": true + }, + { + "Name": "Fr\u00FCh", + "Icon": "\uD83C\uDF05", + "MorningTime": "06:00-14:00", + "AfternoonTime": "", + "IsPngIcon": false + }, + { + "Name": "Sp\u00E4t", + "Icon": "\uD83C\uDF06", + "MorningTime": "", + "AfternoonTime": "14:00-22:00", + "IsPngIcon": false + }, + { + "Name": "Tag", + "Icon": "\u2600\uFE0F", + "MorningTime": "08:00-12:00", + "AfternoonTime": "13:00-17:00", + "IsPngIcon": false + } +] \ No newline at end of file diff --git a/Server/config/transport.json b/Server/config/transport.json new file mode 100644 index 0000000..fde03b0 --- /dev/null +++ b/Server/config/transport.json @@ -0,0 +1,10 @@ +{ + "StartStation": "Modified Station", + "EndStation": "Modified End", + "ApiBaseUrl": "http://modified.com/v1", + "SafetyBufferMinutes": 45, + "MinBreakMinutes": 90, + "MaxEarlyArrivalMinutes": 90, + "MaxLateArrivalMinutes": 30, + "CacheDurationDays": 2 +} \ No newline at end of file diff --git a/Services/ConfigurationService.cs b/Services/ConfigurationService.cs index 7903f61..7aac9d8 100644 --- a/Services/ConfigurationService.cs +++ b/Services/ConfigurationService.cs @@ -17,10 +17,27 @@ namespace ShiftScheduler.Services { private ApplicationConfiguration _configuration; private readonly object _lock = new object(); + private readonly string _configDirectory; + private readonly string _shiftsFilePath; + private readonly string _transportFilePath; public ConfigurationService(ApplicationConfiguration initialConfiguration) { - _configuration = initialConfiguration; + _configDirectory = Path.Combine(Directory.GetCurrentDirectory(), "config"); + _shiftsFilePath = Path.Combine(_configDirectory, "shifts.json"); + _transportFilePath = Path.Combine(_configDirectory, "transport.json"); + + // Ensure config directory exists + Directory.CreateDirectory(_configDirectory); + + // Load configuration from external files if they exist, otherwise use provided configuration + _configuration = LoadConfigurationFromFiles(initialConfiguration); + + // If no external files existed, save the initial configuration to create them + if (!File.Exists(_shiftsFilePath) || !File.Exists(_transportFilePath)) + { + SaveConfigurationToFiles(_configuration); + } } public ApplicationConfiguration GetConfiguration() @@ -76,6 +93,9 @@ namespace ShiftScheduler.Services AfternoonTime = s.AfternoonTime }).ToList() }; + + // Persist changes to external files + SaveConfigurationToFiles(_configuration); } } @@ -107,5 +127,76 @@ namespace ShiftScheduler.Services { return GetConfiguration().Transport; } + + private ApplicationConfiguration LoadConfigurationFromFiles(ApplicationConfiguration fallbackConfiguration) + { + try + { + var shifts = LoadShiftsFromFile() ?? fallbackConfiguration.Shifts; + var transport = LoadTransportFromFile() ?? fallbackConfiguration.Transport; + + return new ApplicationConfiguration + { + Transport = transport, + Shifts = shifts + }; + } + catch + { + // If any error occurs loading from files, use fallback configuration + return fallbackConfiguration; + } + } + + private List? LoadShiftsFromFile() + { + if (!File.Exists(_shiftsFilePath)) + return null; + + try + { + var json = File.ReadAllText(_shiftsFilePath); + return JsonSerializer.Deserialize>(json); + } + catch + { + return null; + } + } + + private TransportConfiguration? LoadTransportFromFile() + { + if (!File.Exists(_transportFilePath)) + return null; + + try + { + var json = File.ReadAllText(_transportFilePath); + return JsonSerializer.Deserialize(json); + } + catch + { + return null; + } + } + + private void SaveConfigurationToFiles(ApplicationConfiguration configuration) + { + try + { + var jsonOptions = new JsonSerializerOptions { WriteIndented = true }; + + var shiftsJson = JsonSerializer.Serialize(configuration.Shifts, jsonOptions); + File.WriteAllText(_shiftsFilePath, shiftsJson); + + var transportJson = JsonSerializer.Serialize(configuration.Transport, jsonOptions); + File.WriteAllText(_transportFilePath, transportJson); + } + catch + { + // Log error if needed, but don't throw to avoid breaking the application + // In a production app, you'd want proper logging here + } + } } } \ No newline at end of file