diff --git a/NEW/JdeScoping.slnx b/NEW/JdeScoping.slnx
index 5233f45..d6f9ec9 100644
--- a/NEW/JdeScoping.slnx
+++ b/NEW/JdeScoping.slnx
@@ -12,6 +12,8 @@
+
+
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager.Cli/Commands/SecretCommands.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Cli/Commands/SecretCommands.cs
new file mode 100644
index 0000000..a5ec5cf
--- /dev/null
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Cli/Commands/SecretCommands.cs
@@ -0,0 +1,389 @@
+using System.CommandLine;
+using JdeScoping.ConfigManager.Core.Services;
+using JdeScoping.ConfigManager.Core.Services.SecureStore;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace JdeScoping.ConfigManager.Cli.Commands;
+
+///
+/// Secret management command implementations.
+///
+public static class SecretCommands
+{
+ ///
+ /// Creates the secret list command.
+ ///
+ public static Command CreateListCommand(
+ IServiceProvider serviceProvider,
+ Option configPathOption,
+ Option verboseOption,
+ Option quietOption)
+ {
+ var command = new Command("list", "List all secret keys");
+
+ command.SetHandler(async (string? configPath, bool verbose, bool quiet) =>
+ {
+ var exitCode = await ListSecretsAsync(serviceProvider, configPath, verbose, quiet);
+ Environment.ExitCode = exitCode;
+ }, configPathOption, verboseOption, quietOption);
+
+ return command;
+ }
+
+ ///
+ /// Creates the secret get command.
+ ///
+ public static Command CreateGetCommand(
+ IServiceProvider serviceProvider,
+ Option configPathOption,
+ Option verboseOption,
+ Option quietOption)
+ {
+ var command = new Command("get", "Get a secret value");
+
+ var keyArgument = new Argument("key", "The secret key to retrieve");
+ command.AddArgument(keyArgument);
+
+ command.SetHandler(async (string? configPath, bool verbose, bool quiet, string key) =>
+ {
+ var exitCode = await GetSecretAsync(serviceProvider, configPath, verbose, quiet, key);
+ Environment.ExitCode = exitCode;
+ }, configPathOption, verboseOption, quietOption, keyArgument);
+
+ return command;
+ }
+
+ ///
+ /// Creates the secret set command.
+ ///
+ public static Command CreateSetCommand(
+ IServiceProvider serviceProvider,
+ Option configPathOption,
+ Option verboseOption,
+ Option quietOption)
+ {
+ var command = new Command("set", "Set or update a secret");
+
+ var keyArgument = new Argument("key", "The secret key");
+ var valueArgument = new Argument("value", "The secret value");
+ command.AddArgument(keyArgument);
+ command.AddArgument(valueArgument);
+
+ command.SetHandler(async (string? configPath, bool verbose, bool quiet, string key, string value) =>
+ {
+ var exitCode = await SetSecretAsync(serviceProvider, configPath, verbose, quiet, key, value);
+ Environment.ExitCode = exitCode;
+ }, configPathOption, verboseOption, quietOption, keyArgument, valueArgument);
+
+ return command;
+ }
+
+ ///
+ /// Creates the secret remove command.
+ ///
+ public static Command CreateRemoveCommand(
+ IServiceProvider serviceProvider,
+ Option configPathOption,
+ Option verboseOption,
+ Option quietOption)
+ {
+ var command = new Command("remove", "Remove a secret");
+
+ var keyArgument = new Argument("key", "The secret key to remove");
+ command.AddArgument(keyArgument);
+
+ command.SetHandler(async (string? configPath, bool verbose, bool quiet, string key) =>
+ {
+ var exitCode = await RemoveSecretAsync(serviceProvider, configPath, verbose, quiet, key);
+ Environment.ExitCode = exitCode;
+ }, configPathOption, verboseOption, quietOption, keyArgument);
+
+ return command;
+ }
+
+ ///
+ /// Creates the secret init command.
+ ///
+ public static Command CreateInitCommand(
+ IServiceProvider serviceProvider,
+ Option configPathOption,
+ Option verboseOption,
+ Option quietOption)
+ {
+ var command = new Command("init", "Initialize a new SecureStore");
+
+ var storePathOption = new Option(
+ aliases: ["--store", "-s"],
+ description: "Path for the store file");
+
+ var keyPathOption = new Option(
+ aliases: ["--key", "-k"],
+ description: "Path for the key file");
+
+ command.AddOption(storePathOption);
+ command.AddOption(keyPathOption);
+
+ command.SetHandler(async (string? configPath, bool verbose, bool quiet, string? storePath, string? keyPath) =>
+ {
+ var exitCode = await InitStoreAsync(serviceProvider, configPath, verbose, quiet, storePath, keyPath);
+ Environment.ExitCode = exitCode;
+ }, configPathOption, verboseOption, quietOption, storePathOption, keyPathOption);
+
+ return command;
+ }
+
+ private static async Task ListSecretsAsync(
+ IServiceProvider serviceProvider,
+ string? configPath,
+ bool verbose,
+ bool quiet)
+ {
+ var (manager, folderPath) = await OpenStoreAsync(serviceProvider, configPath);
+ if (manager == null)
+ return 1;
+
+ try
+ {
+ var keys = manager.GetKeys();
+
+ if (!quiet)
+ {
+ Console.WriteLine($"=== SecureStore Keys ({keys.Count}) ===");
+ }
+
+ foreach (var key in keys.OrderBy(k => k))
+ {
+ Console.WriteLine(key);
+ }
+
+ return 0;
+ }
+ finally
+ {
+ manager.CloseStore();
+ }
+ }
+
+ private static async Task GetSecretAsync(
+ IServiceProvider serviceProvider,
+ string? configPath,
+ bool verbose,
+ bool quiet,
+ string key)
+ {
+ var (manager, folderPath) = await OpenStoreAsync(serviceProvider, configPath);
+ if (manager == null)
+ return 1;
+
+ try
+ {
+ var value = manager.GetSecret(key);
+ Console.WriteLine(value);
+ return 0;
+ }
+ catch (KeyNotFoundException)
+ {
+ Console.Error.WriteLine($"Error: Secret '{key}' not found");
+ return 1;
+ }
+ finally
+ {
+ manager.CloseStore();
+ }
+ }
+
+ private static async Task SetSecretAsync(
+ IServiceProvider serviceProvider,
+ string? configPath,
+ bool verbose,
+ bool quiet,
+ string key,
+ string value)
+ {
+ var (manager, folderPath) = await OpenStoreAsync(serviceProvider, configPath);
+ if (manager == null)
+ return 1;
+
+ try
+ {
+ manager.SetSecret(key, value);
+ manager.Save();
+
+ if (!quiet)
+ {
+ Console.WriteLine($"Secret '{key}' set successfully");
+ }
+
+ return 0;
+ }
+ catch (Exception ex)
+ {
+ Console.Error.WriteLine($"Error: {ex.Message}");
+ return 1;
+ }
+ finally
+ {
+ manager.CloseStore();
+ }
+ }
+
+ private static async Task RemoveSecretAsync(
+ IServiceProvider serviceProvider,
+ string? configPath,
+ bool verbose,
+ bool quiet,
+ string key)
+ {
+ var (manager, folderPath) = await OpenStoreAsync(serviceProvider, configPath);
+ if (manager == null)
+ return 1;
+
+ try
+ {
+ manager.RemoveSecret(key);
+ manager.Save();
+
+ if (!quiet)
+ {
+ Console.WriteLine($"Secret '{key}' removed successfully");
+ }
+
+ return 0;
+ }
+ catch (KeyNotFoundException)
+ {
+ Console.Error.WriteLine($"Error: Secret '{key}' not found");
+ return 1;
+ }
+ catch (Exception ex)
+ {
+ Console.Error.WriteLine($"Error: {ex.Message}");
+ return 1;
+ }
+ finally
+ {
+ manager.CloseStore();
+ }
+ }
+
+ private static async Task InitStoreAsync(
+ IServiceProvider serviceProvider,
+ string? configPath,
+ bool verbose,
+ bool quiet,
+ string? storePath,
+ string? keyPath)
+ {
+ var folderPath = await GetConfigFolderAsync(serviceProvider, configPath);
+ if (folderPath == null)
+ {
+ Console.Error.WriteLine("Error: Could not find configuration folder. Use --config-path to specify.");
+ return 1;
+ }
+
+ var effectiveStorePath = storePath ?? Path.Combine(folderPath, "data", "secrets.json");
+ var effectiveKeyPath = keyPath ?? Path.Combine(folderPath, "data", "secrets.key");
+
+ if (File.Exists(effectiveStorePath))
+ {
+ Console.Error.WriteLine($"Error: Store already exists at {effectiveStorePath}");
+ return 1;
+ }
+
+ var manager = serviceProvider.GetRequiredService();
+
+ try
+ {
+ manager.CreateStore(effectiveStorePath, effectiveKeyPath);
+
+ if (!quiet)
+ {
+ Console.WriteLine("SecureStore initialized successfully");
+ Console.WriteLine($"Store: {effectiveStorePath}");
+ Console.WriteLine($"Key: {effectiveKeyPath}");
+ }
+
+ return 0;
+ }
+ catch (Exception ex)
+ {
+ Console.Error.WriteLine($"Error creating store: {ex.Message}");
+ return 1;
+ }
+ finally
+ {
+ manager.CloseStore();
+ }
+ }
+
+ private static async Task<(ISecureStoreManager?, string?)> OpenStoreAsync(
+ IServiceProvider serviceProvider,
+ string? configPath)
+ {
+ var folderPath = await GetConfigFolderAsync(serviceProvider, configPath);
+ if (folderPath == null)
+ {
+ Console.Error.WriteLine("Error: Could not find configuration folder. Use --config-path to specify.");
+ return (null, null);
+ }
+
+ // Load config to get SecureStore paths
+ var configFileService = serviceProvider.GetRequiredService();
+ var appSettingsPath = Path.Combine(folderPath, "appsettings.json");
+
+ if (!File.Exists(appSettingsPath))
+ {
+ Console.Error.WriteLine($"Error: appsettings.json not found at {appSettingsPath}");
+ return (null, null);
+ }
+
+ try
+ {
+ var config = await configFileService.LoadAppSettingsAsync(appSettingsPath);
+
+ var storePath = Path.IsPathRooted(config.SecureStore.StorePath)
+ ? config.SecureStore.StorePath
+ : Path.Combine(folderPath, config.SecureStore.StorePath);
+
+ var keyPath = Path.IsPathRooted(config.SecureStore.KeyFilePath)
+ ? config.SecureStore.KeyFilePath
+ : Path.Combine(folderPath, config.SecureStore.KeyFilePath);
+
+ if (!File.Exists(storePath))
+ {
+ Console.Error.WriteLine($"Error: SecureStore not found at {storePath}");
+ Console.Error.WriteLine("Use 'secret init' to create a new store.");
+ return (null, null);
+ }
+
+ if (!File.Exists(keyPath))
+ {
+ Console.Error.WriteLine($"Error: Key file not found at {keyPath}");
+ return (null, null);
+ }
+
+ var manager = serviceProvider.GetRequiredService();
+ manager.OpenStore(storePath, keyPath);
+
+ return (manager, folderPath);
+ }
+ catch (Exception ex)
+ {
+ Console.Error.WriteLine($"Error opening store: {ex.Message}");
+ return (null, null);
+ }
+ }
+
+ private static async Task GetConfigFolderAsync(IServiceProvider serviceProvider, string? configPath)
+ {
+ if (!string.IsNullOrEmpty(configPath))
+ {
+ if (Directory.Exists(configPath))
+ return configPath;
+ return null;
+ }
+
+ var autoDiscoveryService = serviceProvider.GetRequiredService();
+ return await autoDiscoveryService.FindConfigFolderAsync();
+ }
+}
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager.Cli/Commands/TestConnectionCommand.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Cli/Commands/TestConnectionCommand.cs
new file mode 100644
index 0000000..a564474
--- /dev/null
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Cli/Commands/TestConnectionCommand.cs
@@ -0,0 +1,243 @@
+using System.CommandLine;
+using JdeScoping.ConfigManager.Core.Models;
+using JdeScoping.ConfigManager.Core.Services;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace JdeScoping.ConfigManager.Cli.Commands;
+
+///
+/// Test connection command implementations.
+///
+public static class TestConnectionCommand
+{
+ ///
+ /// Creates the test-connection sql command.
+ ///
+ public static Command CreateSqlCommand(
+ IServiceProvider serviceProvider,
+ Option configPathOption,
+ Option verboseOption,
+ Option quietOption)
+ {
+ var command = new Command("sql", "Test SQL Server connection");
+
+ var connectionNameOption = new Option(
+ aliases: ["--name", "-n"],
+ description: "Name of the connection string to test");
+
+ command.AddOption(connectionNameOption);
+
+ command.SetHandler(async (string? configPath, bool verbose, bool quiet, string? connectionName) =>
+ {
+ var exitCode = await TestConnectionAsync(serviceProvider, configPath, verbose, quiet, connectionName, ConnectionProvider.SqlServer);
+ Environment.ExitCode = exitCode;
+ }, configPathOption, verboseOption, quietOption, connectionNameOption);
+
+ return command;
+ }
+
+ ///
+ /// Creates the test-connection oracle command.
+ ///
+ public static Command CreateOracleCommand(
+ IServiceProvider serviceProvider,
+ Option configPathOption,
+ Option verboseOption,
+ Option quietOption)
+ {
+ var command = new Command("oracle", "Test Oracle connection");
+
+ var connectionNameOption = new Option(
+ aliases: ["--name", "-n"],
+ description: "Name of the connection string to test");
+
+ command.AddOption(connectionNameOption);
+
+ command.SetHandler(async (string? configPath, bool verbose, bool quiet, string? connectionName) =>
+ {
+ var exitCode = await TestConnectionAsync(serviceProvider, configPath, verbose, quiet, connectionName, ConnectionProvider.Oracle);
+ Environment.ExitCode = exitCode;
+ }, configPathOption, verboseOption, quietOption, connectionNameOption);
+
+ return command;
+ }
+
+ ///
+ /// Creates the test-connection all command.
+ ///
+ public static Command CreateAllCommand(
+ IServiceProvider serviceProvider,
+ Option configPathOption,
+ Option verboseOption,
+ Option quietOption)
+ {
+ var command = new Command("all", "Test all configured connections");
+
+ command.SetHandler(async (string? configPath, bool verbose, bool quiet) =>
+ {
+ var exitCode = await TestAllConnectionsAsync(serviceProvider, configPath, verbose, quiet);
+ Environment.ExitCode = exitCode;
+ }, configPathOption, verboseOption, quietOption);
+
+ return command;
+ }
+
+ private static async Task TestConnectionAsync(
+ IServiceProvider serviceProvider,
+ string? configPath,
+ bool verbose,
+ bool quiet,
+ string? connectionName,
+ ConnectionProvider provider)
+ {
+ var folderPath = await GetConfigFolderAsync(serviceProvider, configPath);
+ if (folderPath == null)
+ {
+ Console.Error.WriteLine("Error: Could not find configuration folder. Use --config-path to specify.");
+ return 1;
+ }
+
+ var configFileService = serviceProvider.GetRequiredService();
+ var connectionTestService = serviceProvider.GetRequiredService();
+
+ var appSettingsPath = Path.Combine(folderPath, "appsettings.json");
+ if (!File.Exists(appSettingsPath))
+ {
+ Console.Error.WriteLine($"Error: appsettings.json not found at {appSettingsPath}");
+ return 1;
+ }
+
+ try
+ {
+ var config = await configFileService.LoadAppSettingsAsync(appSettingsPath);
+
+ var entry = connectionName != null
+ ? config.ConnectionStrings.Entries.FirstOrDefault(e =>
+ e.Name.Equals(connectionName, StringComparison.OrdinalIgnoreCase))
+ : config.ConnectionStrings.Entries.FirstOrDefault(e => e.Provider == provider);
+
+ if (entry == null)
+ {
+ var message = connectionName != null
+ ? $"Connection '{connectionName}' not found"
+ : $"No {provider} connection found";
+ Console.Error.WriteLine($"Error: {message}");
+ return 1;
+ }
+
+ if (!quiet)
+ {
+ Console.WriteLine($"Testing connection: {entry.Name}");
+ }
+
+ var connectionString = entry.GenerateConnectionString();
+ var result = await connectionTestService.TestConnectionAsync(connectionString, entry.Provider);
+
+ if (result.Success)
+ {
+ if (!quiet)
+ {
+ Console.WriteLine($"Status: Success");
+ if (result.Duration.HasValue)
+ Console.WriteLine($"Duration: {result.Duration.Value.TotalMilliseconds:F0}ms");
+ }
+ return 0;
+ }
+
+ Console.Error.WriteLine($"Status: Failed");
+ Console.Error.WriteLine($"Message: {result.Message}");
+ return 1;
+ }
+ catch (Exception ex)
+ {
+ Console.Error.WriteLine($"Error: {ex.Message}");
+ return 1;
+ }
+ }
+
+ private static async Task TestAllConnectionsAsync(
+ IServiceProvider serviceProvider,
+ string? configPath,
+ bool verbose,
+ bool quiet)
+ {
+ var folderPath = await GetConfigFolderAsync(serviceProvider, configPath);
+ if (folderPath == null)
+ {
+ Console.Error.WriteLine("Error: Could not find configuration folder. Use --config-path to specify.");
+ return 1;
+ }
+
+ var configFileService = serviceProvider.GetRequiredService();
+ var connectionTestService = serviceProvider.GetRequiredService();
+
+ var appSettingsPath = Path.Combine(folderPath, "appsettings.json");
+ if (!File.Exists(appSettingsPath))
+ {
+ Console.Error.WriteLine($"Error: appsettings.json not found at {appSettingsPath}");
+ return 1;
+ }
+
+ try
+ {
+ var config = await configFileService.LoadAppSettingsAsync(appSettingsPath);
+ var hasFailures = false;
+
+ if (!quiet)
+ {
+ Console.WriteLine("=== Testing All Connections ===");
+ Console.WriteLine($"Found {config.ConnectionStrings.Entries.Count} connection(s)");
+ Console.WriteLine();
+ }
+
+ foreach (var entry in config.ConnectionStrings.Entries)
+ {
+ if (entry.Provider == ConnectionProvider.Generic)
+ {
+ if (!quiet)
+ Console.WriteLine($"{entry.Name}: Skipped (generic provider)");
+ continue;
+ }
+
+ var connectionString = entry.GenerateConnectionString();
+ var result = await connectionTestService.TestConnectionAsync(connectionString, entry.Provider);
+
+ if (result.Success)
+ {
+ if (!quiet)
+ {
+ var duration = result.Duration.HasValue
+ ? $" ({result.Duration.Value.TotalMilliseconds:F0}ms)"
+ : "";
+ Console.WriteLine($"{entry.Name}: OK{duration}");
+ }
+ }
+ else
+ {
+ hasFailures = true;
+ Console.Error.WriteLine($"{entry.Name}: FAILED - {result.Message}");
+ }
+ }
+
+ return hasFailures ? 1 : 0;
+ }
+ catch (Exception ex)
+ {
+ Console.Error.WriteLine($"Error: {ex.Message}");
+ return 1;
+ }
+ }
+
+ private static async Task GetConfigFolderAsync(IServiceProvider serviceProvider, string? configPath)
+ {
+ if (!string.IsNullOrEmpty(configPath))
+ {
+ if (Directory.Exists(configPath))
+ return configPath;
+ return null;
+ }
+
+ var autoDiscoveryService = serviceProvider.GetRequiredService();
+ return await autoDiscoveryService.FindConfigFolderAsync();
+ }
+}
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager.Cli/Commands/ValidateCommand.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Cli/Commands/ValidateCommand.cs
new file mode 100644
index 0000000..83247f9
--- /dev/null
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Cli/Commands/ValidateCommand.cs
@@ -0,0 +1,273 @@
+using System.CommandLine;
+using JdeScoping.ConfigManager.Core.Services;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace JdeScoping.ConfigManager.Cli.Commands;
+
+///
+/// Validation command implementations.
+///
+public static class ValidateCommand
+{
+ ///
+ /// Creates the validate appsettings command.
+ ///
+ public static Command CreateAppSettingsCommand(
+ IServiceProvider serviceProvider,
+ Option configPathOption,
+ Option verboseOption,
+ Option quietOption)
+ {
+ var command = new Command("appsettings", "Validate appsettings.json");
+
+ command.SetHandler(async (string? configPath, bool verbose, bool quiet) =>
+ {
+ var exitCode = await ValidateAppSettingsAsync(serviceProvider, configPath, verbose, quiet);
+ Environment.ExitCode = exitCode;
+ }, configPathOption, verboseOption, quietOption);
+
+ return command;
+ }
+
+ ///
+ /// Creates the validate pipelines command.
+ ///
+ public static Command CreatePipelinesCommand(
+ IServiceProvider serviceProvider,
+ Option configPathOption,
+ Option verboseOption,
+ Option quietOption)
+ {
+ var command = new Command("pipelines", "Validate pipeline configuration files");
+
+ command.SetHandler(async (string? configPath, bool verbose, bool quiet) =>
+ {
+ var exitCode = await ValidatePipelinesAsync(serviceProvider, configPath, verbose, quiet);
+ Environment.ExitCode = exitCode;
+ }, configPathOption, verboseOption, quietOption);
+
+ return command;
+ }
+
+ ///
+ /// Creates the validate all command.
+ ///
+ public static Command CreateAllCommand(
+ IServiceProvider serviceProvider,
+ Option configPathOption,
+ Option verboseOption,
+ Option quietOption)
+ {
+ var command = new Command("all", "Validate all configuration files");
+
+ command.SetHandler(async (string? configPath, bool verbose, bool quiet) =>
+ {
+ var exitCode1 = await ValidateAppSettingsAsync(serviceProvider, configPath, verbose, quiet);
+ var exitCode2 = await ValidatePipelinesAsync(serviceProvider, configPath, verbose, quiet);
+ Environment.ExitCode = Math.Max(exitCode1, exitCode2);
+ }, configPathOption, verboseOption, quietOption);
+
+ return command;
+ }
+
+ ///
+ /// Creates the validate runtime command.
+ ///
+ public static Command CreateRuntimeCommand(
+ IServiceProvider serviceProvider,
+ Option configPathOption,
+ Option verboseOption,
+ Option quietOption)
+ {
+ var command = new Command("runtime", "Run Infrastructure validators");
+
+ command.SetHandler(async (string? configPath, bool verbose, bool quiet) =>
+ {
+ var exitCode = await ValidateRuntimeAsync(serviceProvider, configPath, verbose, quiet);
+ Environment.ExitCode = exitCode;
+ }, configPathOption, verboseOption, quietOption);
+
+ return command;
+ }
+
+ private static async Task ValidateAppSettingsAsync(
+ IServiceProvider serviceProvider,
+ string? configPath,
+ bool verbose,
+ bool quiet)
+ {
+ var folderPath = await GetConfigFolderAsync(serviceProvider, configPath);
+ if (folderPath == null)
+ {
+ Console.Error.WriteLine("Error: Could not find configuration folder. Use --config-path to specify.");
+ return 1;
+ }
+
+ var configFileService = serviceProvider.GetRequiredService();
+ var validationService = serviceProvider.GetRequiredService();
+
+ var appSettingsPath = Path.Combine(folderPath, "appsettings.json");
+ if (!File.Exists(appSettingsPath))
+ {
+ Console.Error.WriteLine($"Error: appsettings.json not found at {appSettingsPath}");
+ return 1;
+ }
+
+ try
+ {
+ var config = await configFileService.LoadAppSettingsAsync(appSettingsPath);
+ var result = validationService.ValidateAppSettings(config);
+
+ if (!quiet)
+ {
+ Console.WriteLine("=== AppSettings Validation ===");
+ Console.WriteLine($"File: {appSettingsPath}");
+ }
+
+ if (result.IsValid)
+ {
+ if (!quiet)
+ Console.WriteLine("Status: Valid");
+ return 0;
+ }
+
+ foreach (var error in result.Errors)
+ {
+ Console.Error.WriteLine($"Error: {error}");
+ }
+
+ foreach (var warning in result.Warnings)
+ {
+ if (!quiet)
+ Console.WriteLine($"Warning: {warning}");
+ }
+
+ return 1;
+ }
+ catch (ConfigLoadException ex)
+ {
+ Console.Error.WriteLine($"Error loading configuration: {ex.Message}");
+ return 1;
+ }
+ }
+
+ private static async Task ValidatePipelinesAsync(
+ IServiceProvider serviceProvider,
+ string? configPath,
+ bool verbose,
+ bool quiet)
+ {
+ var folderPath = await GetConfigFolderAsync(serviceProvider, configPath);
+ if (folderPath == null)
+ {
+ Console.Error.WriteLine("Error: Could not find configuration folder. Use --config-path to specify.");
+ return 1;
+ }
+
+ var configFileService = serviceProvider.GetRequiredService();
+ var validationService = serviceProvider.GetRequiredService();
+
+ var pipelinesDir = Path.Combine(folderPath, "Pipelines");
+
+ try
+ {
+ var pipelines = await configFileService.LoadAllPipelinesAsync(pipelinesDir);
+ var result = validationService.ValidatePipelines(pipelines);
+
+ if (!quiet)
+ {
+ Console.WriteLine("=== Pipelines Validation ===");
+ Console.WriteLine($"Directory: {pipelinesDir}");
+ Console.WriteLine($"Pipelines found: {pipelines.Count}");
+ }
+
+ if (result.IsValid)
+ {
+ if (!quiet)
+ Console.WriteLine("Status: Valid");
+ return 0;
+ }
+
+ foreach (var error in result.Errors)
+ {
+ Console.Error.WriteLine($"Error: {error}");
+ }
+
+ foreach (var warning in result.Warnings)
+ {
+ if (!quiet)
+ Console.WriteLine($"Warning: {warning}");
+ }
+
+ return result.Errors.Count > 0 ? 1 : 0;
+ }
+ catch (Exception ex)
+ {
+ Console.Error.WriteLine($"Error validating pipelines: {ex.Message}");
+ return 1;
+ }
+ }
+
+ private static async Task ValidateRuntimeAsync(
+ IServiceProvider serviceProvider,
+ string? configPath,
+ bool verbose,
+ bool quiet)
+ {
+ var folderPath = await GetConfigFolderAsync(serviceProvider, configPath);
+ if (folderPath == null)
+ {
+ Console.Error.WriteLine("Error: Could not find configuration folder. Use --config-path to specify.");
+ return 1;
+ }
+
+ var runtimeValidationService = serviceProvider.GetRequiredService();
+
+ if (!quiet)
+ {
+ Console.WriteLine("=== Runtime Configuration Validation ===");
+ Console.WriteLine($"Folder: {folderPath}");
+ }
+
+ var results = runtimeValidationService.ValidateRuntimeConfig(folderPath);
+ var hasErrors = false;
+
+ foreach (var result in results)
+ {
+ if (result.Errors.Count > 0)
+ {
+ hasErrors = true;
+ Console.Error.WriteLine($"\n[{result.ValidatorName}]");
+ foreach (var error in result.Errors)
+ {
+ Console.Error.WriteLine($" Error: {error}");
+ }
+ }
+ else if (!quiet)
+ {
+ Console.WriteLine($"[{result.ValidatorName}]: OK");
+ }
+
+ foreach (var warning in result.Warnings)
+ {
+ if (!quiet)
+ Console.WriteLine($" Warning: {warning}");
+ }
+ }
+
+ return hasErrors ? 1 : 0;
+ }
+
+ private static async Task GetConfigFolderAsync(IServiceProvider serviceProvider, string? configPath)
+ {
+ if (!string.IsNullOrEmpty(configPath))
+ {
+ if (Directory.Exists(configPath))
+ return configPath;
+ return null;
+ }
+
+ var autoDiscoveryService = serviceProvider.GetRequiredService();
+ return await autoDiscoveryService.FindConfigFolderAsync();
+ }
+}
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager.Cli/JdeScoping.ConfigManager.Cli.csproj b/NEW/src/Utils/JdeScoping.ConfigManager.Cli/JdeScoping.ConfigManager.Cli.csproj
new file mode 100644
index 0000000..a9759dd
--- /dev/null
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Cli/JdeScoping.ConfigManager.Cli.csproj
@@ -0,0 +1,20 @@
+
+
+ Exe
+ net10.0
+ enable
+ enable
+ jdescoping-config
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager.Cli/Program.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Cli/Program.cs
new file mode 100644
index 0000000..8fbc60a
--- /dev/null
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Cli/Program.cs
@@ -0,0 +1,82 @@
+using System.CommandLine;
+using JdeScoping.ConfigManager.Cli.Commands;
+using JdeScoping.ConfigManager.Core.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+
+namespace JdeScoping.ConfigManager.Cli;
+
+///
+/// Main entry point for the jdescoping-config CLI tool.
+///
+public static class Program
+{
+ ///
+ /// Main entry point.
+ ///
+ /// Command-line arguments.
+ /// Exit code: 0 for success, non-zero for errors.
+ public static async Task Main(string[] args)
+ {
+ var services = new ServiceCollection();
+ ConfigureServices(services);
+ using var serviceProvider = services.BuildServiceProvider();
+
+ var rootCommand = new RootCommand("JDE Scoping Tool configuration management CLI")
+ {
+ Name = "jdescoping-config"
+ };
+
+ // Global options
+ var configPathOption = new Option(
+ aliases: ["--config-path", "-c"],
+ description: "Path to configuration folder");
+
+ var verboseOption = new Option(
+ aliases: ["--verbose", "-v"],
+ description: "Enable verbose output");
+
+ var quietOption = new Option(
+ aliases: ["--quiet", "-q"],
+ description: "Suppress non-error output");
+
+ rootCommand.AddGlobalOption(configPathOption);
+ rootCommand.AddGlobalOption(verboseOption);
+ rootCommand.AddGlobalOption(quietOption);
+
+ // Validate command group
+ var validateCommand = new Command("validate", "Validate configuration files");
+ validateCommand.AddCommand(ValidateCommand.CreateAppSettingsCommand(serviceProvider, configPathOption, verboseOption, quietOption));
+ validateCommand.AddCommand(ValidateCommand.CreatePipelinesCommand(serviceProvider, configPathOption, verboseOption, quietOption));
+ validateCommand.AddCommand(ValidateCommand.CreateAllCommand(serviceProvider, configPathOption, verboseOption, quietOption));
+ validateCommand.AddCommand(ValidateCommand.CreateRuntimeCommand(serviceProvider, configPathOption, verboseOption, quietOption));
+ rootCommand.AddCommand(validateCommand);
+
+ // Test-connection command group
+ var testConnectionCommand = new Command("test-connection", "Test database connections");
+ testConnectionCommand.AddCommand(TestConnectionCommand.CreateSqlCommand(serviceProvider, configPathOption, verboseOption, quietOption));
+ testConnectionCommand.AddCommand(TestConnectionCommand.CreateOracleCommand(serviceProvider, configPathOption, verboseOption, quietOption));
+ testConnectionCommand.AddCommand(TestConnectionCommand.CreateAllCommand(serviceProvider, configPathOption, verboseOption, quietOption));
+ rootCommand.AddCommand(testConnectionCommand);
+
+ // Secret command group
+ var secretCommand = new Command("secret", "Manage SecureStore secrets");
+ secretCommand.AddCommand(SecretCommands.CreateListCommand(serviceProvider, configPathOption, verboseOption, quietOption));
+ secretCommand.AddCommand(SecretCommands.CreateGetCommand(serviceProvider, configPathOption, verboseOption, quietOption));
+ secretCommand.AddCommand(SecretCommands.CreateSetCommand(serviceProvider, configPathOption, verboseOption, quietOption));
+ secretCommand.AddCommand(SecretCommands.CreateRemoveCommand(serviceProvider, configPathOption, verboseOption, quietOption));
+ secretCommand.AddCommand(SecretCommands.CreateInitCommand(serviceProvider, configPathOption, verboseOption, quietOption));
+ rootCommand.AddCommand(secretCommand);
+
+ return await rootCommand.InvokeAsync(args);
+ }
+
+ private static void ConfigureServices(IServiceCollection services)
+ {
+ services.AddLogging(builder => builder
+ .AddConsole()
+ .SetMinimumLevel(LogLevel.Warning));
+
+ services.AddConfigManagerCore();
+ }
+}
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Application/SecretUseCases.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Application/SecretUseCases.cs
similarity index 91%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Application/SecretUseCases.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Application/SecretUseCases.cs
index ac6a19f..05dc150 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Application/SecretUseCases.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Application/SecretUseCases.cs
@@ -1,7 +1,7 @@
using Microsoft.Extensions.Logging;
-using JdeScoping.ConfigManager.Services.SecureStore;
+using JdeScoping.ConfigManager.Core.Services.SecureStore;
-namespace JdeScoping.ConfigManager.Application;
+namespace JdeScoping.ConfigManager.Core.Application;
///
/// Secret CRUD use-case operations with logging.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Application/StoreUseCases.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Application/StoreUseCases.cs
similarity index 94%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Application/StoreUseCases.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Application/StoreUseCases.cs
index e864a73..956a1e0 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Application/StoreUseCases.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Application/StoreUseCases.cs
@@ -1,7 +1,7 @@
using Microsoft.Extensions.Logging;
-using JdeScoping.ConfigManager.Services.SecureStore;
+using JdeScoping.ConfigManager.Core.Services.SecureStore;
-namespace JdeScoping.ConfigManager.Application;
+namespace JdeScoping.ConfigManager.Core.Application;
///
/// Store lifecycle use-case operations with logging.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Constants/SecureStoreFileExtensions.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Constants/SecureStoreFileExtensions.cs
similarity index 89%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Constants/SecureStoreFileExtensions.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Constants/SecureStoreFileExtensions.cs
index 7586e0a..72464f5 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Constants/SecureStoreFileExtensions.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Constants/SecureStoreFileExtensions.cs
@@ -1,4 +1,4 @@
-namespace JdeScoping.ConfigManager.Constants;
+namespace JdeScoping.ConfigManager.Core.Constants;
///
/// Centralized constants for secure store file extensions and patterns used in file dialogs.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Constants/SecureStoreStrings.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Constants/SecureStoreStrings.cs
similarity index 96%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Constants/SecureStoreStrings.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Constants/SecureStoreStrings.cs
index aae7077..e3f1589 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Constants/SecureStoreStrings.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Constants/SecureStoreStrings.cs
@@ -1,4 +1,4 @@
-namespace JdeScoping.ConfigManager.Constants;
+namespace JdeScoping.ConfigManager.Core.Constants;
///
/// Centralized string constants for secure store dialog titles, messages, and validation errors.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager.Core/DependencyInjection/ServiceCollectionExtensions.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/DependencyInjection/ServiceCollectionExtensions.cs
new file mode 100644
index 0000000..097bc99
--- /dev/null
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/DependencyInjection/ServiceCollectionExtensions.cs
@@ -0,0 +1,43 @@
+using JdeScoping.ConfigManager.Core.Application;
+using JdeScoping.ConfigManager.Core.Services;
+using JdeScoping.ConfigManager.Core.Services.SecureStore;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace JdeScoping.ConfigManager.Core.DependencyInjection;
+
+///
+/// Extension methods for registering ConfigManager.Core services with dependency injection.
+///
+public static class ServiceCollectionExtensions
+{
+ ///
+ /// Adds ConfigManager.Core services to the service collection.
+ ///
+ /// The service collection to add services to.
+ /// The service collection for chaining.
+ public static IServiceCollection AddConfigManagerCore(this IServiceCollection services)
+ {
+ // File system abstraction
+ services.AddSingleton();
+
+ // Configuration management services
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddScoped();
+
+ // SecureStore services
+ services.AddSingleton();
+ services.AddSingleton();
+ services.AddSingleton();
+
+ // Runtime validation
+ services.AddSingleton();
+
+ // Connection testing
+ services.AddSingleton();
+
+ return services;
+ }
+}
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager.Core/JdeScoping.ConfigManager.Core.csproj b/NEW/src/Utils/JdeScoping.ConfigManager.Core/JdeScoping.ConfigManager.Core.csproj
new file mode 100644
index 0000000..c953f94
--- /dev/null
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/JdeScoping.ConfigManager.Core.csproj
@@ -0,0 +1,22 @@
+
+
+ net10.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Models/ConfigModel.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Models/ConfigModel.cs
similarity index 95%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Models/ConfigModel.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Models/ConfigModel.cs
index 9914ee6..695c6c6 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Models/ConfigModel.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Models/ConfigModel.cs
@@ -1,6 +1,4 @@
-using System.Text.Json.Serialization;
-
-namespace JdeScoping.ConfigManager.Models;
+namespace JdeScoping.ConfigManager.Core.Models;
///
/// Root model for appsettings.json configuration.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Models/ConnectionProvider.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Models/ConnectionProvider.cs
similarity index 74%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Models/ConnectionProvider.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Models/ConnectionProvider.cs
index e1fa8a2..4ddc978 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Models/ConnectionProvider.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Models/ConnectionProvider.cs
@@ -1,4 +1,4 @@
-namespace JdeScoping.ConfigManager.Models;
+namespace JdeScoping.ConfigManager.Core.Models;
///
/// Database provider types supported by the ConnectionStrings editor.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Models/ConnectionStringEntry.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Models/ConnectionStringEntry.cs
similarity index 96%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Models/ConnectionStringEntry.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Models/ConnectionStringEntry.cs
index 6c61f82..ee849f6 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Models/ConnectionStringEntry.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Models/ConnectionStringEntry.cs
@@ -1,4 +1,4 @@
-namespace JdeScoping.ConfigManager.Models;
+namespace JdeScoping.ConfigManager.Core.Models;
///
/// Represents a single connection string entry with provider-specific fields.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Models/ConnectionStringsSection.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Models/ConnectionStringsSection.cs
similarity index 88%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Models/ConnectionStringsSection.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Models/ConnectionStringsSection.cs
index 1cb59b7..cd1d97d 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Models/ConnectionStringsSection.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Models/ConnectionStringsSection.cs
@@ -1,6 +1,6 @@
using System.Text.Json.Serialization;
-namespace JdeScoping.ConfigManager.Models;
+namespace JdeScoping.ConfigManager.Core.Models;
///
/// Configuration section for connection strings.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Models/ConnectionStringsSectionConverter.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Models/ConnectionStringsSectionConverter.cs
similarity index 93%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Models/ConnectionStringsSectionConverter.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Models/ConnectionStringsSectionConverter.cs
index 5d81755..3f62765 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Models/ConnectionStringsSectionConverter.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Models/ConnectionStringsSectionConverter.cs
@@ -1,7 +1,7 @@
using System.Text.Json;
using System.Text.Json.Serialization;
-namespace JdeScoping.ConfigManager.Models;
+namespace JdeScoping.ConfigManager.Core.Models;
///
/// Custom JSON converter that handles the standard .NET ConnectionStrings dictionary format
@@ -215,7 +215,12 @@ public class ConnectionStringsSectionConverter : JsonConverter
+ /// Applies a connection string to an existing entry, parsing it according to the detected provider.
+ ///
+ /// The entry to update.
+ /// The connection string to parse and apply.
+ public static void ApplyConnectionString(ConnectionStringEntry entry, string connectionString)
{
var parsed = ParseConnectionString(entry.Name, connectionString);
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/AutoDiscoveryService.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/AutoDiscoveryService.cs
similarity index 96%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Services/AutoDiscoveryService.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/AutoDiscoveryService.cs
index f1ec81f..11e3ca1 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Services/AutoDiscoveryService.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/AutoDiscoveryService.cs
@@ -1,6 +1,6 @@
using Microsoft.Extensions.Logging;
-namespace JdeScoping.ConfigManager.Services;
+namespace JdeScoping.ConfigManager.Core.Services;
///
/// Service for auto-discovering configuration file locations.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/BackupInfo.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/BackupInfo.cs
new file mode 100644
index 0000000..16a656c
--- /dev/null
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/BackupInfo.cs
@@ -0,0 +1,22 @@
+namespace JdeScoping.ConfigManager.Core.Services;
+
+///
+/// Represents backup file information.
+///
+public class BackupInfo
+{
+ ///
+ /// Gets the full path to the backup file.
+ ///
+ public required string Path { get; init; }
+
+ ///
+ /// Gets the timestamp when the backup was created.
+ ///
+ public required DateTime Timestamp { get; init; }
+
+ ///
+ /// Gets the file size in bytes.
+ ///
+ public required long Size { get; init; }
+}
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/BackupService.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/BackupService.cs
similarity index 96%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Services/BackupService.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/BackupService.cs
index 5bec3ff..823407d 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Services/BackupService.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/BackupService.cs
@@ -1,7 +1,7 @@
using System.Globalization;
using Microsoft.Extensions.Logging;
-namespace JdeScoping.ConfigManager.Services;
+namespace JdeScoping.ConfigManager.Core.Services;
///
/// Service for managing configuration file backups.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/ConfigFileService.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/ConfigFileService.cs
similarity index 96%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Services/ConfigFileService.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/ConfigFileService.cs
index 325dd06..0e428d4 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Services/ConfigFileService.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/ConfigFileService.cs
@@ -1,10 +1,10 @@
using System.Text.Json;
using System.Text.Json.Serialization;
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
using JdeScoping.DataSync.Configuration;
using Microsoft.Extensions.Logging;
-namespace JdeScoping.ConfigManager.Services;
+namespace JdeScoping.ConfigManager.Core.Services;
///
/// Service for loading and saving configuration files.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/ConfigLoadException.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/ConfigLoadException.cs
similarity index 91%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Services/ConfigLoadException.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/ConfigLoadException.cs
index c0d6f8b..50451e6 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Services/ConfigLoadException.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/ConfigLoadException.cs
@@ -1,4 +1,4 @@
-namespace JdeScoping.ConfigManager.Services;
+namespace JdeScoping.ConfigManager.Core.Services;
///
/// Exception thrown when configuration file loading fails.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/ConnectionTestResult.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/ConnectionTestResult.cs
new file mode 100644
index 0000000..f2e7789
--- /dev/null
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/ConnectionTestResult.cs
@@ -0,0 +1,22 @@
+namespace JdeScoping.ConfigManager.Core.Services;
+
+///
+/// Result of testing a database connection.
+///
+public class ConnectionTestResult
+{
+ ///
+ /// Gets a value indicating whether the connection test was successful.
+ ///
+ public bool Success { get; init; }
+
+ ///
+ /// Gets the message describing the result of the connection test.
+ ///
+ public string Message { get; init; } = string.Empty;
+
+ ///
+ /// Gets the elapsed time of the connection test operation.
+ ///
+ public TimeSpan? Duration { get; init; }
+}
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/ConnectionTestService.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/ConnectionTestService.cs
similarity index 94%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Services/ConnectionTestService.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/ConnectionTestService.cs
index 853d4fd..0a8aa8c 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Services/ConnectionTestService.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/ConnectionTestService.cs
@@ -1,8 +1,8 @@
using System.Diagnostics;
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
using Microsoft.Data.SqlClient;
-namespace JdeScoping.ConfigManager.Services;
+namespace JdeScoping.ConfigManager.Core.Services;
///
/// Service for testing database connections.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/IDiffService.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/DiffResult.cs
similarity index 69%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Services/IDiffService.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/DiffResult.cs
index 8d0ef61..8847746 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Services/IDiffService.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/DiffResult.cs
@@ -1,4 +1,4 @@
-namespace JdeScoping.ConfigManager.Services;
+namespace JdeScoping.ConfigManager.Core.Services;
///
/// Represents a line in a diff output.
@@ -58,17 +58,3 @@ public class DiffResult
///
public int Deletions { get; init; }
}
-
-///
-/// Service for generating diffs between text content.
-///
-public interface IDiffService
-{
- ///
- /// Generates a diff between original and modified text content.
- ///
- /// The original text content.
- /// The modified text content.
- /// A diff result containing added, removed, and unchanged lines with counts.
- DiffResult GenerateDiff(string original, string modified);
-}
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/DiffService.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/DiffService.cs
similarity index 94%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Services/DiffService.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/DiffService.cs
index 7235c49..101be62 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Services/DiffService.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/DiffService.cs
@@ -2,7 +2,7 @@ using DiffPlex;
using DiffPlex.DiffBuilder;
using DiffPlex.DiffBuilder.Model;
-namespace JdeScoping.ConfigManager.Services;
+namespace JdeScoping.ConfigManager.Core.Services;
///
/// Service for generating diffs between text content.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/FileSystem.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/FileSystem.cs
similarity index 96%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Services/FileSystem.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/FileSystem.cs
index dcc5c18..b15d46b 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Services/FileSystem.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/FileSystem.cs
@@ -1,4 +1,4 @@
-namespace JdeScoping.ConfigManager.Services;
+namespace JdeScoping.ConfigManager.Core.Services;
///
/// Real file system implementation.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/IAutoDiscoveryService.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IAutoDiscoveryService.cs
similarity index 91%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Services/IAutoDiscoveryService.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IAutoDiscoveryService.cs
index 4372214..78be821 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Services/IAutoDiscoveryService.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IAutoDiscoveryService.cs
@@ -1,4 +1,4 @@
-namespace JdeScoping.ConfigManager.Services;
+namespace JdeScoping.ConfigManager.Core.Services;
///
/// Service for auto-discovering configuration file locations.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/IBackupService.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IBackupService.cs
similarity index 76%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Services/IBackupService.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IBackupService.cs
index fcfc101..cb3c596 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Services/IBackupService.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IBackupService.cs
@@ -1,25 +1,4 @@
-namespace JdeScoping.ConfigManager.Services;
-
-///
-/// Represents backup file information.
-///
-public class BackupInfo
-{
- ///
- /// Gets the full path to the backup file.
- ///
- public required string Path { get; init; }
-
- ///
- /// Gets the timestamp when the backup was created.
- ///
- public required DateTime Timestamp { get; init; }
-
- ///
- /// Gets the file size in bytes.
- ///
- public required long Size { get; init; }
-}
+namespace JdeScoping.ConfigManager.Core.Services;
///
/// Service for managing configuration file backups.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/IConfigFileService.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IConfigFileService.cs
similarity index 94%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Services/IConfigFileService.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IConfigFileService.cs
index 463da40..e6c9f89 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Services/IConfigFileService.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IConfigFileService.cs
@@ -1,7 +1,7 @@
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
using JdeScoping.DataSync.Configuration;
-namespace JdeScoping.ConfigManager.Services;
+namespace JdeScoping.ConfigManager.Core.Services;
///
/// Service for loading and saving configuration files.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IConnectionTestService.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IConnectionTestService.cs
new file mode 100644
index 0000000..aac4dfc
--- /dev/null
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IConnectionTestService.cs
@@ -0,0 +1,18 @@
+using JdeScoping.ConfigManager.Core.Models;
+
+namespace JdeScoping.ConfigManager.Core.Services;
+
+///
+/// Service for testing database connections.
+///
+public interface IConnectionTestService
+{
+ ///
+ /// Tests a database connection asynchronously.
+ ///
+ /// The connection string to test.
+ /// The database provider type.
+ /// Cancellation token for the operation.
+ /// A ConnectionTestResult indicating success or failure of the test.
+ Task TestConnectionAsync(string connectionString, ConnectionProvider provider, CancellationToken cancellationToken = default);
+}
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IDiffService.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IDiffService.cs
new file mode 100644
index 0000000..16a7b72
--- /dev/null
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IDiffService.cs
@@ -0,0 +1,15 @@
+namespace JdeScoping.ConfigManager.Core.Services;
+
+///
+/// Service for generating diffs between text content.
+///
+public interface IDiffService
+{
+ ///
+ /// Generates a diff between original and modified text content.
+ ///
+ /// The original text content.
+ /// The modified text content.
+ /// A diff result containing added, removed, and unchanged lines with counts.
+ DiffResult GenerateDiff(string original, string modified);
+}
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/IFileSystem.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IFileSystem.cs
similarity index 96%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Services/IFileSystem.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IFileSystem.cs
index cbee86e..502fa4e 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Services/IFileSystem.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IFileSystem.cs
@@ -1,4 +1,4 @@
-namespace JdeScoping.ConfigManager.Services;
+namespace JdeScoping.ConfigManager.Core.Services;
///
/// Abstraction for file system operations to enable testing.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IRuntimeConfigValidationService.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IRuntimeConfigValidationService.cs
new file mode 100644
index 0000000..0c814dd
--- /dev/null
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IRuntimeConfigValidationService.cs
@@ -0,0 +1,14 @@
+namespace JdeScoping.ConfigManager.Core.Services;
+
+///
+/// Service for validating runtime configuration using Infrastructure validators.
+///
+public interface IRuntimeConfigValidationService
+{
+ ///
+ /// Validates the configuration in the specified folder using Infrastructure validators.
+ ///
+ /// Path to the configuration folder.
+ /// List of validation results from each validator.
+ List ValidateRuntimeConfig(string configFolderPath);
+}
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/IValidationService.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IValidationService.cs
similarity index 52%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Services/IValidationService.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IValidationService.cs
index 106ea90..5a154da 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Services/IValidationService.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/IValidationService.cs
@@ -1,40 +1,7 @@
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
using JdeScoping.DataSync.Configuration;
-namespace JdeScoping.ConfigManager.Services;
-
-///
-/// Result of a validation operation.
-///
-public class ValidationResult
-{
- ///
- /// Gets a value indicating whether the validation succeeded (no errors).
- ///
- public bool IsValid => Errors.Count == 0;
-
- ///
- /// Gets the list of validation errors encountered.
- ///
- public List Errors { get; } = [];
-
- ///
- /// Gets the list of validation warnings encountered.
- ///
- public List Warnings { get; } = [];
-
- ///
- /// Adds an error message to the validation result.
- ///
- /// The error message to add.
- public void AddError(string message) => Errors.Add(message);
-
- ///
- /// Adds a warning message to the validation result.
- ///
- /// The warning message to add.
- public void AddWarning(string message) => Warnings.Add(message);
-}
+namespace JdeScoping.ConfigManager.Core.Services;
///
/// Service for validating configuration files.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/RuntimeConfigValidationService.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/RuntimeConfigValidationService.cs
similarity index 95%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Services/RuntimeConfigValidationService.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/RuntimeConfigValidationService.cs
index afc02c2..0e38725 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Services/RuntimeConfigValidationService.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/RuntimeConfigValidationService.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Services.SecureStore;
+using JdeScoping.ConfigManager.Core.Services.SecureStore;
using JdeScoping.Core.Interfaces;
using JdeScoping.Core.Validation;
using Microsoft.Extensions.Configuration;
@@ -6,7 +6,7 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
-namespace JdeScoping.ConfigManager.Services;
+namespace JdeScoping.ConfigManager.Core.Services;
///
/// Service that validates configuration using Infrastructure validators.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/IRuntimeConfigValidationService.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/RuntimeValidationResult.cs
similarity index 52%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Services/IRuntimeConfigValidationService.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/RuntimeValidationResult.cs
index a9bdb91..c88758a 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Services/IRuntimeConfigValidationService.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/RuntimeValidationResult.cs
@@ -1,4 +1,4 @@
-namespace JdeScoping.ConfigManager.Services;
+namespace JdeScoping.ConfigManager.Core.Services;
///
/// Result of runtime configuration validation.
@@ -25,16 +25,3 @@ public class RuntimeValidationResult
///
public List Warnings { get; } = [];
}
-
-///
-/// Service for validating runtime configuration using Infrastructure validators.
-///
-public interface IRuntimeConfigValidationService
-{
- ///
- /// Validates the configuration in the specified folder using Infrastructure validators.
- ///
- /// Path to the configuration folder.
- /// List of validation results from each validator.
- List ValidateRuntimeConfig(string configFolderPath);
-}
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/SecureStore/ISecureStoreManager.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/SecureStore/ISecureStoreManager.cs
similarity index 95%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Services/SecureStore/ISecureStoreManager.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/SecureStore/ISecureStoreManager.cs
index f64000e..78526eb 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Services/SecureStore/ISecureStoreManager.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/SecureStore/ISecureStoreManager.cs
@@ -1,4 +1,4 @@
-namespace JdeScoping.ConfigManager.Services.SecureStore;
+namespace JdeScoping.ConfigManager.Core.Services.SecureStore;
///
/// Interface for managing SecureStore encrypted secret stores.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/SecureStore/SecureStoreManager.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/SecureStore/SecureStoreManager.cs
similarity index 95%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Services/SecureStore/SecureStoreManager.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/SecureStore/SecureStoreManager.cs
index 2986102..34f4469 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Services/SecureStore/SecureStoreManager.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/SecureStore/SecureStoreManager.cs
@@ -1,13 +1,12 @@
-using System.IO;
using System.Text.Json;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using NeoSmart.SecureStore;
-namespace JdeScoping.ConfigManager.Services.SecureStore;
+namespace JdeScoping.ConfigManager.Core.Services.SecureStore;
///
-/// Manages SecureStore encrypted secret stores for the Avalonia application.
+/// Manages SecureStore encrypted secret stores.
///
public class SecureStoreManager : ISecureStoreManager, IDisposable
{
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/SecureStoreServiceAdapter.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/SecureStoreServiceAdapter.cs
similarity index 91%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Services/SecureStoreServiceAdapter.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/SecureStoreServiceAdapter.cs
index 2c90732..b72d3a8 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Services/SecureStoreServiceAdapter.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/SecureStoreServiceAdapter.cs
@@ -1,7 +1,7 @@
-using JdeScoping.ConfigManager.Services.SecureStore;
+using JdeScoping.ConfigManager.Core.Services.SecureStore;
using JdeScoping.Core.Interfaces;
-namespace JdeScoping.ConfigManager.Services;
+namespace JdeScoping.ConfigManager.Core.Services;
///
/// Adapts ISecureStoreManager to ISecureStoreService for use by Infrastructure validators.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/ValidationResult.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/ValidationResult.cs
new file mode 100644
index 0000000..ca31769
--- /dev/null
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/ValidationResult.cs
@@ -0,0 +1,34 @@
+namespace JdeScoping.ConfigManager.Core.Services;
+
+///
+/// Result of a validation operation.
+///
+public class ValidationResult
+{
+ ///
+ /// Gets a value indicating whether the validation succeeded (no errors).
+ ///
+ public bool IsValid => Errors.Count == 0;
+
+ ///
+ /// Gets the list of validation errors encountered.
+ ///
+ public List Errors { get; } = [];
+
+ ///
+ /// Gets the list of validation warnings encountered.
+ ///
+ public List Warnings { get; } = [];
+
+ ///
+ /// Adds an error message to the validation result.
+ ///
+ /// The error message to add.
+ public void AddError(string message) => Errors.Add(message);
+
+ ///
+ /// Adds a warning message to the validation result.
+ ///
+ /// The warning message to add.
+ public void AddWarning(string message) => Warnings.Add(message);
+}
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/ValidationService.cs b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/ValidationService.cs
similarity index 96%
rename from NEW/src/Utils/JdeScoping.ConfigManager/Services/ValidationService.cs
rename to NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/ValidationService.cs
index bed9eae..ac8a244 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Services/ValidationService.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager.Core/Services/ValidationService.cs
@@ -1,7 +1,7 @@
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
using JdeScoping.DataSync.Configuration;
-namespace JdeScoping.ConfigManager.Services;
+namespace JdeScoping.ConfigManager.Core.Services;
///
/// Service for validating configuration files.
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/App.axaml.cs b/NEW/src/Utils/JdeScoping.ConfigManager/App.axaml.cs
index 36dbacb..ca8a27c 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/App.axaml.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/App.axaml.cs
@@ -3,9 +3,8 @@ using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Input.Platform;
using Avalonia.Markup.Xaml;
-using JdeScoping.ConfigManager.Application;
+using JdeScoping.ConfigManager.Core.DependencyInjection;
using JdeScoping.ConfigManager.Services;
-using JdeScoping.ConfigManager.Services.SecureStore;
using JdeScoping.ConfigManager.ViewModels;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@@ -50,33 +49,15 @@ public partial class App : Avalonia.Application
.AddConsole()
.SetMinimumLevel(LogLevel.Debug));
- // Services - File system abstraction
- services.AddSingleton();
+ // Add all ConfigManager.Core services
+ services.AddConfigManagerCore();
- // Services - Configuration management
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddScoped();
-
- // Platform Services
+ // Platform Services (Avalonia-specific)
services.AddSingleton(sp =>
new AvaloniaDialogService(GetMainWindow));
services.AddSingleton(sp =>
new AvaloniaClipboardService(GetClipboard));
- // SecureStore Services
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
-
- // Runtime Validation Services
- services.AddSingleton();
-
- // Connection Testing
- services.AddSingleton();
-
// ViewModels
services.AddTransient();
}
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Converters/ProviderToVisibilityConverter.cs b/NEW/src/Utils/JdeScoping.ConfigManager/Converters/ProviderToVisibilityConverter.cs
index a6660a2..5e96e14 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Converters/ProviderToVisibilityConverter.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/Converters/ProviderToVisibilityConverter.cs
@@ -1,6 +1,6 @@
using System.Globalization;
using Avalonia.Data.Converters;
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
namespace JdeScoping.ConfigManager.Converters;
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/JdeScoping.ConfigManager.csproj b/NEW/src/Utils/JdeScoping.ConfigManager/JdeScoping.ConfigManager.csproj
index d7d3868..1702b8f 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/JdeScoping.ConfigManager.csproj
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/JdeScoping.ConfigManager.csproj
@@ -16,22 +16,15 @@
-
-
-
-
-
-
-
-
+
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/AvaloniaDialogService.cs b/NEW/src/Utils/JdeScoping.ConfigManager/Services/AvaloniaDialogService.cs
index 93fd47a..6de2fb1 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Services/AvaloniaDialogService.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/Services/AvaloniaDialogService.cs
@@ -1,6 +1,7 @@
using System.Text;
using Avalonia.Controls;
using Avalonia.Platform.Storage;
+using JdeScoping.ConfigManager.Core.Services;
using JdeScoping.ConfigManager.Views.Dialogs;
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/IConnectionTestService.cs b/NEW/src/Utils/JdeScoping.ConfigManager/Services/IConnectionTestService.cs
deleted file mode 100644
index 4964a6a..0000000
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Services/IConnectionTestService.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using JdeScoping.ConfigManager.Models;
-
-namespace JdeScoping.ConfigManager.Services;
-
-///
-/// Result of testing a database connection.
-///
-public class ConnectionTestResult
-{
- ///
- /// Gets a value indicating whether the connection test was successful.
- ///
- public bool Success { get; init; }
-
- ///
- /// Gets the message describing the result of the connection test.
- ///
- public string Message { get; init; } = string.Empty;
-
- ///
- /// Gets the elapsed time of the connection test operation.
- ///
- public TimeSpan? Duration { get; init; }
-}
-
-///
-/// Service for testing database connections.
-///
-public interface IConnectionTestService
-{
- ///
- /// Tests a database connection asynchronously.
- ///
- /// The connection string to test.
- /// The database provider type.
- /// Cancellation token for the operation.
- /// A ConnectionTestResult indicating success or failure of the test.
- Task TestConnectionAsync(string connectionString, ConnectionProvider provider, CancellationToken cancellationToken = default);
-}
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/IDialogService.cs b/NEW/src/Utils/JdeScoping.ConfigManager/Services/IDialogService.cs
index 5d0a5b1..c9cbc6b 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Services/IDialogService.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/Services/IDialogService.cs
@@ -1,3 +1,5 @@
+using JdeScoping.ConfigManager.Core.Services;
+
namespace JdeScoping.ConfigManager.Services;
///
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Dialogs/DiffPreviewDialogViewModel.cs b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Dialogs/DiffPreviewDialogViewModel.cs
index 4cbac97..5408329 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Dialogs/DiffPreviewDialogViewModel.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Dialogs/DiffPreviewDialogViewModel.cs
@@ -1,6 +1,6 @@
using System.Collections.ObjectModel;
using System.Windows.Input;
-using JdeScoping.ConfigManager.Services;
+using JdeScoping.ConfigManager.Core.Services;
namespace JdeScoping.ConfigManager.ViewModels.Dialogs;
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Dialogs/NewStoreDialogViewModel.cs b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Dialogs/NewStoreDialogViewModel.cs
index e2abe8f..90a3ac3 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Dialogs/NewStoreDialogViewModel.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Dialogs/NewStoreDialogViewModel.cs
@@ -1,5 +1,5 @@
using System.Windows.Input;
-using JdeScoping.ConfigManager.Constants;
+using JdeScoping.ConfigManager.Core.Constants;
namespace JdeScoping.ConfigManager.ViewModels.Dialogs;
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Dialogs/SecretEditDialogViewModel.cs b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Dialogs/SecretEditDialogViewModel.cs
index f162983..6abc1a8 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Dialogs/SecretEditDialogViewModel.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Dialogs/SecretEditDialogViewModel.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Constants;
+using JdeScoping.ConfigManager.Core.Constants;
namespace JdeScoping.ConfigManager.ViewModels.Dialogs;
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Dialogs/UnlockStoreDialogViewModel.cs b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Dialogs/UnlockStoreDialogViewModel.cs
index d063fcc..1c701da 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Dialogs/UnlockStoreDialogViewModel.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Dialogs/UnlockStoreDialogViewModel.cs
@@ -1,5 +1,5 @@
using System.Windows.Input;
-using JdeScoping.ConfigManager.Constants;
+using JdeScoping.ConfigManager.Core.Constants;
namespace JdeScoping.ConfigManager.ViewModels.Dialogs;
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Dialogs/ValidationResultsDialogViewModel.cs b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Dialogs/ValidationResultsDialogViewModel.cs
index 5432194..da9e415 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Dialogs/ValidationResultsDialogViewModel.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Dialogs/ValidationResultsDialogViewModel.cs
@@ -1,6 +1,6 @@
using System.Collections.ObjectModel;
using System.Windows.Input;
-using JdeScoping.ConfigManager.Services;
+using JdeScoping.ConfigManager.Core.Services;
namespace JdeScoping.ConfigManager.ViewModels.Dialogs;
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/AuthFormViewModel.cs b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/AuthFormViewModel.cs
index 7de2382..3dbfa18 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/AuthFormViewModel.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/AuthFormViewModel.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
namespace JdeScoping.ConfigManager.ViewModels.Forms;
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/ConnectionStringEntryViewModel.cs b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/ConnectionStringEntryViewModel.cs
index 021c2ec..1541bfc 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/ConnectionStringEntryViewModel.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/ConnectionStringEntryViewModel.cs
@@ -1,5 +1,5 @@
using System.Windows.Input;
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
namespace JdeScoping.ConfigManager.ViewModels.Forms;
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/ConnectionStringsFormViewModel.cs b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/ConnectionStringsFormViewModel.cs
index 7494ad9..161bc9c 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/ConnectionStringsFormViewModel.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/ConnectionStringsFormViewModel.cs
@@ -1,8 +1,9 @@
using System.Collections.ObjectModel;
using System.Windows.Input;
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
+using JdeScoping.ConfigManager.Core.Services;
+using JdeScoping.ConfigManager.Core.Services.SecureStore;
using JdeScoping.ConfigManager.Services;
-using JdeScoping.ConfigManager.Services.SecureStore;
namespace JdeScoping.ConfigManager.ViewModels.Forms;
@@ -52,10 +53,10 @@ public class ConnectionStringsFormViewModel : ViewModelBase
: null;
// Update entry's RawConnectionString with SecureStore value if available
- if (!string.IsNullOrEmpty(secureStoreValue))
- {
- ConnectionStringsSectionConverter.ApplyConnectionString(entry, secureStoreValue);
- }
+ if (!string.IsNullOrEmpty(secureStoreValue))
+ {
+ ConnectionStringsSectionConverter.ApplyConnectionString(entry, secureStoreValue);
+ }
Connections.Add(new ConnectionStringEntryViewModel(entry, OnEntryChanged));
}
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/DataAccessFormViewModel.cs b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/DataAccessFormViewModel.cs
index c9f8b35..d7a9700 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/DataAccessFormViewModel.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/DataAccessFormViewModel.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
namespace JdeScoping.ConfigManager.ViewModels.Forms;
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/DataSyncFormViewModel.cs b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/DataSyncFormViewModel.cs
index efd67c7..3d71a43 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/DataSyncFormViewModel.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/DataSyncFormViewModel.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
namespace JdeScoping.ConfigManager.ViewModels.Forms;
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/ExcelExportFormViewModel.cs b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/ExcelExportFormViewModel.cs
index 3fd15a7..7bb478a 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/ExcelExportFormViewModel.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/ExcelExportFormViewModel.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
namespace JdeScoping.ConfigManager.ViewModels.Forms;
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/LdapFormViewModel.cs b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/LdapFormViewModel.cs
index 3c8e520..5a27eea 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/LdapFormViewModel.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/LdapFormViewModel.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
namespace JdeScoping.ConfigManager.ViewModels.Forms;
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/SearchFormViewModel.cs b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/SearchFormViewModel.cs
index 60d00e8..42b5ab4 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/SearchFormViewModel.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/Forms/SearchFormViewModel.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
namespace JdeScoping.ConfigManager.ViewModels.Forms;
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/MainWindowViewModel.cs b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/MainWindowViewModel.cs
index 27f89f7..9ec3c66 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/MainWindowViewModel.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/ViewModels/MainWindowViewModel.cs
@@ -1,10 +1,11 @@
using System.Collections.ObjectModel;
using System.Windows.Input;
using Avalonia.Media;
-using JdeScoping.ConfigManager.Constants;
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Constants;
+using JdeScoping.ConfigManager.Core.Models;
+using JdeScoping.ConfigManager.Core.Services;
+using JdeScoping.ConfigManager.Core.Services.SecureStore;
using JdeScoping.ConfigManager.Services;
-using JdeScoping.ConfigManager.Services.SecureStore;
using JdeScoping.ConfigManager.ViewModels.Dialogs;
using JdeScoping.ConfigManager.ViewModels.Forms;
using JdeScoping.DataSync.Configuration;
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Views/Dialogs/NewStoreDialog.axaml.cs b/NEW/src/Utils/JdeScoping.ConfigManager/Views/Dialogs/NewStoreDialog.axaml.cs
index b890669..fa2e714 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Views/Dialogs/NewStoreDialog.axaml.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/Views/Dialogs/NewStoreDialog.axaml.cs
@@ -1,8 +1,8 @@
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Platform.Storage;
-using JdeScoping.ConfigManager.Constants;
-using JdeScoping.ConfigManager.Services.SecureStore;
+using JdeScoping.ConfigManager.Core.Constants;
+using JdeScoping.ConfigManager.Core.Services.SecureStore;
using JdeScoping.ConfigManager.ViewModels.Dialogs;
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Views/Dialogs/SecretEditDialog.axaml.cs b/NEW/src/Utils/JdeScoping.ConfigManager/Views/Dialogs/SecretEditDialog.axaml.cs
index ef82a58..92daca9 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Views/Dialogs/SecretEditDialog.axaml.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/Views/Dialogs/SecretEditDialog.axaml.cs
@@ -1,6 +1,6 @@
using Avalonia.Controls;
using Avalonia.Interactivity;
-using JdeScoping.ConfigManager.Constants;
+using JdeScoping.ConfigManager.Core.Constants;
using JdeScoping.ConfigManager.ViewModels.Dialogs;
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Views/Dialogs/UnlockStoreDialog.axaml.cs b/NEW/src/Utils/JdeScoping.ConfigManager/Views/Dialogs/UnlockStoreDialog.axaml.cs
index f3efc29..9a5b33b 100644
--- a/NEW/src/Utils/JdeScoping.ConfigManager/Views/Dialogs/UnlockStoreDialog.axaml.cs
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/Views/Dialogs/UnlockStoreDialog.axaml.cs
@@ -1,7 +1,7 @@
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Platform.Storage;
-using JdeScoping.ConfigManager.Constants;
+using JdeScoping.ConfigManager.Core.Constants;
using JdeScoping.ConfigManager.ViewModels.Dialogs;
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/JdeScoping.ConfigManager.Tests.csproj b/NEW/tests/JdeScoping.ConfigManager.Tests/JdeScoping.ConfigManager.Tests.csproj
index 987dbc7..824f469 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/JdeScoping.ConfigManager.Tests.csproj
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/JdeScoping.ConfigManager.Tests.csproj
@@ -8,6 +8,7 @@
+
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/Models/ConnectionStringEntryTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/Models/ConnectionStringEntryTests.cs
index f38163e..e4fffd5 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/Models/ConnectionStringEntryTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/Models/ConnectionStringEntryTests.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
namespace JdeScoping.ConfigManager.Tests.Models;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/Models/ConnectionStringsSectionConverterTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/Models/ConnectionStringsSectionConverterTests.cs
index af669da..bf609cf 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/Models/ConnectionStringsSectionConverterTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/Models/ConnectionStringsSectionConverterTests.cs
@@ -1,5 +1,5 @@
using System.Text.Json;
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
using Shouldly;
using Xunit;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/Services/AutoDiscoveryServiceTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/Services/AutoDiscoveryServiceTests.cs
index 6d8c8b3..4865b62 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/Services/AutoDiscoveryServiceTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/Services/AutoDiscoveryServiceTests.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Services;
+using JdeScoping.ConfigManager.Core.Services;
namespace JdeScoping.ConfigManager.Tests.Services;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/Services/BackupServiceTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/Services/BackupServiceTests.cs
index 52a7cfe..60bab85 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/Services/BackupServiceTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/Services/BackupServiceTests.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Services;
+using JdeScoping.ConfigManager.Core.Services;
namespace JdeScoping.ConfigManager.Tests.Services;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/Services/ConfigFileServiceTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/Services/ConfigFileServiceTests.cs
index ef255d4..292e2ba 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/Services/ConfigFileServiceTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/Services/ConfigFileServiceTests.cs
@@ -1,5 +1,5 @@
-using JdeScoping.ConfigManager.Models;
-using JdeScoping.ConfigManager.Services;
+using JdeScoping.ConfigManager.Core.Models;
+using JdeScoping.ConfigManager.Core.Services;
using JdeScoping.DataSync.Configuration;
namespace JdeScoping.ConfigManager.Tests.Services;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/Services/ConnectionTestServiceTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/Services/ConnectionTestServiceTests.cs
index 4296e2c..42a0e1f 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/Services/ConnectionTestServiceTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/Services/ConnectionTestServiceTests.cs
@@ -1,5 +1,5 @@
-using JdeScoping.ConfigManager.Models;
-using JdeScoping.ConfigManager.Services;
+using JdeScoping.ConfigManager.Core.Models;
+using JdeScoping.ConfigManager.Core.Services;
namespace JdeScoping.ConfigManager.Tests.Services;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/Services/DiffServiceTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/Services/DiffServiceTests.cs
index cba412f..928ccbc 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/Services/DiffServiceTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/Services/DiffServiceTests.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Services;
+using JdeScoping.ConfigManager.Core.Services;
namespace JdeScoping.ConfigManager.Tests.Services;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/Services/FileSystemTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/Services/FileSystemTests.cs
index 64a33ea..e57d143 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/Services/FileSystemTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/Services/FileSystemTests.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Services;
+using JdeScoping.ConfigManager.Core.Services;
namespace JdeScoping.ConfigManager.Tests.Services;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/Services/RuntimeConfigValidationServiceTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/Services/RuntimeConfigValidationServiceTests.cs
index cbb68f4..69f23d9 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/Services/RuntimeConfigValidationServiceTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/Services/RuntimeConfigValidationServiceTests.cs
@@ -1,5 +1,5 @@
-using JdeScoping.ConfigManager.Services;
-using JdeScoping.ConfigManager.Services.SecureStore;
+using JdeScoping.ConfigManager.Core.Services;
+using JdeScoping.ConfigManager.Core.Services.SecureStore;
namespace JdeScoping.ConfigManager.Tests.Services;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/Services/SecureStore/SecureStoreManagerTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/Services/SecureStore/SecureStoreManagerTests.cs
index 06f9b11..497dec4 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/Services/SecureStore/SecureStoreManagerTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/Services/SecureStore/SecureStoreManagerTests.cs
@@ -1,5 +1,5 @@
using System.IO;
-using JdeScoping.ConfigManager.Services.SecureStore;
+using JdeScoping.ConfigManager.Core.Services.SecureStore;
namespace JdeScoping.ConfigManager.Tests.Services.SecureStore;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/Services/ValidationServiceTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/Services/ValidationServiceTests.cs
index 4d6e8a7..910a05f 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/Services/ValidationServiceTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/Services/ValidationServiceTests.cs
@@ -1,5 +1,5 @@
-using JdeScoping.ConfigManager.Models;
-using JdeScoping.ConfigManager.Services;
+using JdeScoping.ConfigManager.Core.Models;
+using JdeScoping.ConfigManager.Core.Services;
using JdeScoping.DataSync.Configuration;
namespace JdeScoping.ConfigManager.Tests.Services;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Dialogs/DiffPreviewDialogViewModelTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Dialogs/DiffPreviewDialogViewModelTests.cs
index e462ab9..979389d 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Dialogs/DiffPreviewDialogViewModelTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Dialogs/DiffPreviewDialogViewModelTests.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Services;
+using JdeScoping.ConfigManager.Core.Services;
using JdeScoping.ConfigManager.ViewModels.Dialogs;
namespace JdeScoping.ConfigManager.Tests.ViewModels.Dialogs;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Dialogs/NewStoreDialogViewModelTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Dialogs/NewStoreDialogViewModelTests.cs
index 63e7d23..3aa0014 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Dialogs/NewStoreDialogViewModelTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Dialogs/NewStoreDialogViewModelTests.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Constants;
+using JdeScoping.ConfigManager.Core.Constants;
using JdeScoping.ConfigManager.ViewModels.Dialogs;
namespace JdeScoping.ConfigManager.Tests.ViewModels.Dialogs;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Dialogs/SecretEditDialogViewModelTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Dialogs/SecretEditDialogViewModelTests.cs
index d9eb4b2..9960f78 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Dialogs/SecretEditDialogViewModelTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Dialogs/SecretEditDialogViewModelTests.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Constants;
+using JdeScoping.ConfigManager.Core.Constants;
using JdeScoping.ConfigManager.ViewModels.Dialogs;
namespace JdeScoping.ConfigManager.Tests.ViewModels.Dialogs;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Dialogs/UnlockStoreDialogViewModelTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Dialogs/UnlockStoreDialogViewModelTests.cs
index 8ee2588..4cbb3eb 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Dialogs/UnlockStoreDialogViewModelTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Dialogs/UnlockStoreDialogViewModelTests.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Constants;
+using JdeScoping.ConfigManager.Core.Constants;
using JdeScoping.ConfigManager.ViewModels.Dialogs;
namespace JdeScoping.ConfigManager.Tests.ViewModels.Dialogs;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Dialogs/ValidationResultsDialogViewModelTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Dialogs/ValidationResultsDialogViewModelTests.cs
index 91809a6..2fcae17 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Dialogs/ValidationResultsDialogViewModelTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Dialogs/ValidationResultsDialogViewModelTests.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Services;
+using JdeScoping.ConfigManager.Core.Services;
using JdeScoping.ConfigManager.ViewModels.Dialogs;
namespace JdeScoping.ConfigManager.Tests.ViewModels.Dialogs;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/AuthFormViewModelTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/AuthFormViewModelTests.cs
index 652966d..f70a30e 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/AuthFormViewModelTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/AuthFormViewModelTests.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
using JdeScoping.ConfigManager.ViewModels.Forms;
namespace JdeScoping.ConfigManager.Tests.ViewModels.Forms;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/ConnectionStringEntryViewModelTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/ConnectionStringEntryViewModelTests.cs
index e50e782..7eeb8c5 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/ConnectionStringEntryViewModelTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/ConnectionStringEntryViewModelTests.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
using JdeScoping.ConfigManager.ViewModels.Forms;
namespace JdeScoping.ConfigManager.Tests.ViewModels.Forms;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/ConnectionStringsFormViewModelTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/ConnectionStringsFormViewModelTests.cs
index f56c287..ee84853 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/ConnectionStringsFormViewModelTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/ConnectionStringsFormViewModelTests.cs
@@ -1,6 +1,7 @@
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
+using JdeScoping.ConfigManager.Core.Services;
+using JdeScoping.ConfigManager.Core.Services.SecureStore;
using JdeScoping.ConfigManager.Services;
-using JdeScoping.ConfigManager.Services.SecureStore;
using JdeScoping.ConfigManager.ViewModels.Forms;
namespace JdeScoping.ConfigManager.Tests.ViewModels.Forms;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/DataAccessFormViewModelTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/DataAccessFormViewModelTests.cs
index 5c1bdd1..586638f 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/DataAccessFormViewModelTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/DataAccessFormViewModelTests.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
using JdeScoping.ConfigManager.ViewModels.Forms;
namespace JdeScoping.ConfigManager.Tests.ViewModels.Forms;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/DataSyncFormViewModelTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/DataSyncFormViewModelTests.cs
index e6dceaa..27d0f85 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/DataSyncFormViewModelTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/DataSyncFormViewModelTests.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
using JdeScoping.ConfigManager.ViewModels.Forms;
namespace JdeScoping.ConfigManager.Tests.ViewModels.Forms;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/ExcelExportFormViewModelTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/ExcelExportFormViewModelTests.cs
index 508b37a..df0ae96 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/ExcelExportFormViewModelTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/ExcelExportFormViewModelTests.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
using JdeScoping.ConfigManager.ViewModels.Forms;
namespace JdeScoping.ConfigManager.Tests.ViewModels.Forms;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/LdapFormViewModelTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/LdapFormViewModelTests.cs
index 64b862d..9bfde87 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/LdapFormViewModelTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/LdapFormViewModelTests.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
using JdeScoping.ConfigManager.ViewModels.Forms;
namespace JdeScoping.ConfigManager.Tests.ViewModels.Forms;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/SearchFormViewModelTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/SearchFormViewModelTests.cs
index 342968d..9a0fc00 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/SearchFormViewModelTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/Forms/SearchFormViewModelTests.cs
@@ -1,4 +1,4 @@
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Models;
using JdeScoping.ConfigManager.ViewModels.Forms;
namespace JdeScoping.ConfigManager.Tests.ViewModels.Forms;
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/MainWindowViewModelTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/MainWindowViewModelTests.cs
index 8b728f0..153cba4 100644
--- a/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/MainWindowViewModelTests.cs
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/ViewModels/MainWindowViewModelTests.cs
@@ -1,7 +1,8 @@
-using JdeScoping.ConfigManager.Constants;
-using JdeScoping.ConfigManager.Models;
+using JdeScoping.ConfigManager.Core.Constants;
+using JdeScoping.ConfigManager.Core.Models;
+using JdeScoping.ConfigManager.Core.Services;
+using JdeScoping.ConfigManager.Core.Services.SecureStore;
using JdeScoping.ConfigManager.Services;
-using JdeScoping.ConfigManager.Services.SecureStore;
using JdeScoping.ConfigManager.ViewModels;
using JdeScoping.ConfigManager.ViewModels.Forms;
using JdeScoping.DataSync.Configuration;