diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/FileSystem.cs b/NEW/src/Utils/JdeScoping.ConfigManager/Services/FileSystem.cs
new file mode 100644
index 0000000..00f5de1
--- /dev/null
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/Services/FileSystem.cs
@@ -0,0 +1,40 @@
+namespace JdeScoping.ConfigManager.Services;
+
+///
+/// Real file system implementation.
+///
+public class FileSystem : IFileSystem
+{
+ public bool FileExists(string path) => File.Exists(path);
+
+ public bool DirectoryExists(string path) => Directory.Exists(path);
+
+ public async Task ReadAllTextAsync(string path, CancellationToken ct = default)
+ => await File.ReadAllTextAsync(path, ct);
+
+ public async Task WriteAllTextAsync(string path, string content, CancellationToken ct = default)
+ => await File.WriteAllTextAsync(path, content, ct);
+
+ public Task GetFilesAsync(string directory, string pattern, CancellationToken ct = default)
+ => Task.FromResult(Directory.GetFiles(directory, pattern));
+
+ public async Task CopyFileAsync(string source, string destination, CancellationToken ct = default)
+ {
+ var content = await File.ReadAllBytesAsync(source, ct);
+ await File.WriteAllBytesAsync(destination, content, ct);
+ }
+
+ public Task DeleteFileAsync(string path, CancellationToken ct = default)
+ {
+ File.Delete(path);
+ return Task.CompletedTask;
+ }
+
+ public string GetDirectoryName(string path) => Path.GetDirectoryName(path) ?? string.Empty;
+
+ public string GetFileName(string path) => Path.GetFileName(path);
+
+ public string GetFileNameWithoutExtension(string path) => Path.GetFileNameWithoutExtension(path);
+
+ public string Combine(params string[] paths) => Path.Combine(paths);
+}
diff --git a/NEW/src/Utils/JdeScoping.ConfigManager/Services/IFileSystem.cs b/NEW/src/Utils/JdeScoping.ConfigManager/Services/IFileSystem.cs
new file mode 100644
index 0000000..b5d265f
--- /dev/null
+++ b/NEW/src/Utils/JdeScoping.ConfigManager/Services/IFileSystem.cs
@@ -0,0 +1,19 @@
+namespace JdeScoping.ConfigManager.Services;
+
+///
+/// Abstraction for file system operations to enable testing.
+///
+public interface IFileSystem
+{
+ bool FileExists(string path);
+ bool DirectoryExists(string path);
+ Task ReadAllTextAsync(string path, CancellationToken ct = default);
+ Task WriteAllTextAsync(string path, string content, CancellationToken ct = default);
+ Task GetFilesAsync(string directory, string pattern, CancellationToken ct = default);
+ Task CopyFileAsync(string source, string destination, CancellationToken ct = default);
+ Task DeleteFileAsync(string path, CancellationToken ct = default);
+ string GetDirectoryName(string path);
+ string GetFileName(string path);
+ string GetFileNameWithoutExtension(string path);
+ string Combine(params string[] paths);
+}
diff --git a/NEW/tests/JdeScoping.ConfigManager.Tests/Services/FileSystemTests.cs b/NEW/tests/JdeScoping.ConfigManager.Tests/Services/FileSystemTests.cs
new file mode 100644
index 0000000..64a33ea
--- /dev/null
+++ b/NEW/tests/JdeScoping.ConfigManager.Tests/Services/FileSystemTests.cs
@@ -0,0 +1,40 @@
+using JdeScoping.ConfigManager.Services;
+
+namespace JdeScoping.ConfigManager.Tests.Services;
+
+public class FileSystemTests
+{
+ [Fact]
+ public void FileExists_WithExistingFile_ReturnsTrue()
+ {
+ // Arrange
+ var sut = new FileSystem();
+ var tempFile = Path.GetTempFileName();
+
+ try
+ {
+ // Act
+ var result = sut.FileExists(tempFile);
+
+ // Assert
+ result.ShouldBeTrue();
+ }
+ finally
+ {
+ File.Delete(tempFile);
+ }
+ }
+
+ [Fact]
+ public void FileExists_WithNonExistingFile_ReturnsFalse()
+ {
+ // Arrange
+ var sut = new FileSystem();
+
+ // Act
+ var result = sut.FileExists("/nonexistent/path/file.txt");
+
+ // Assert
+ result.ShouldBeFalse();
+ }
+}