Przeglądaj źródła

Refactored project

Tim Jones 1 miesiąc temu
rodzic
commit
6de3c52626
100 zmienionych plików z 139 dodań i 3304 usunięć
  1. BIN
      .DS_Store
  2. 1 0
      .run/RackPeek.Web.Viewer_ https.run.xml
  3. 9 1
      RackPeek.Domain/Persistence/Yaml/YamlResourceCollection.cs
  4. 25 0
      RackPeek.Domain/Persistence/YamlSystemRepository.cs
  5. 31 0
      RackPeek.Domain/Resources/Hardware/AccessPoints/CloneAccessPointUseCase.cs
  6. 1 1
      RackPeek.Domain/Resources/Hardware/Desktops/CloneDesktopUsecase.cs
  7. 2 0
      RackPeek.Domain/Resources/SystemResources/ISystemRepository.cs
  8. 0 475
      RackPeek.Web.Viewer/CliBootstrap.cs
  9. 8 4
      RackPeek.Web.Viewer/Pages/Home.razor
  10. 4 4
      RackPeek.Web.Viewer/Program.cs
  11. 0 513
      RackPeek.Web.Viewer/wwwroot/config.yaml
  12. BIN
      RackPeek.Web/.DS_Store
  13. 1 0
      RackPeek.Web/Components/App.razor
  14. 29 7
      RackPeek.Web/Components/Routes.razor
  15. 19 6
      RackPeek.Web/Program.cs
  16. 0 1
      RackPeek.Web/RackPeek.Web.csproj
  17. 9 0
      RackPeek.Web/wwwroot/console.js
  18. BIN
      RackPeek/.DS_Store
  19. 0 11
      RackPeek/Commands/AccessPoints/AccessCommands.cs
  20. 0 33
      RackPeek/Commands/AccessPoints/AccessPointAddCommand.cs
  21. 0 25
      RackPeek/Commands/AccessPoints/AccessPointDeleteCommand.cs
  22. 0 37
      RackPeek/Commands/AccessPoints/AccessPointDescribeCommand.cs
  23. 0 27
      RackPeek/Commands/AccessPoints/AccessPointGetByNameCommand.cs
  24. 0 44
      RackPeek/Commands/AccessPoints/AccessPointGetCommand.cs
  25. 0 43
      RackPeek/Commands/AccessPoints/AccessPointReportCommand.cs
  26. 0 42
      RackPeek/Commands/AccessPoints/AccessPointSetCommand.cs
  27. 0 24
      RackPeek/Commands/Desktops/Cpus/DesktopCpuAddCommand.cs
  28. 0 23
      RackPeek/Commands/Desktops/Cpus/DesktopCpuAddSettings.cs
  29. 0 24
      RackPeek/Commands/Desktops/Cpus/DesktopCpuRemoveCommand.cs
  30. 0 15
      RackPeek/Commands/Desktops/Cpus/DesktopCpuRemoveSettings.cs
  31. 0 25
      RackPeek/Commands/Desktops/Cpus/DesktopCpuSetCommand.cs
  32. 0 27
      RackPeek/Commands/Desktops/Cpus/DesktopCpuSetSettings.cs
  33. 0 24
      RackPeek/Commands/Desktops/DesktopAddCommand.cs
  34. 0 8
      RackPeek/Commands/Desktops/DesktopCommands.cs
  35. 0 24
      RackPeek/Commands/Desktops/DesktopDeleteCommand.cs
  36. 0 35
      RackPeek/Commands/Desktops/DesktopDescribeCommand.cs
  37. 0 24
      RackPeek/Commands/Desktops/DesktopGetByNameCommand.cs
  38. 0 50
      RackPeek/Commands/Desktops/DesktopGetCommand.cs
  39. 0 51
      RackPeek/Commands/Desktops/DesktopReportCommand.cs
  40. 0 29
      RackPeek/Commands/Desktops/DesktopSetCommand.cs
  41. 0 29
      RackPeek/Commands/Desktops/DesktopTreeCommand.cs
  42. 0 24
      RackPeek/Commands/Desktops/Drive/DesktopDriveAddCommand.cs
  43. 0 19
      RackPeek/Commands/Desktops/Drive/DesktopDriveAddSettings.cs
  44. 0 24
      RackPeek/Commands/Desktops/Drive/DesktopDriveRemoveCommand.cs
  45. 0 15
      RackPeek/Commands/Desktops/Drive/DesktopDriveRemoveSettings.cs
  46. 0 24
      RackPeek/Commands/Desktops/Drive/DesktopDriveSetCommand.cs
  47. 0 23
      RackPeek/Commands/Desktops/Drive/DesktopDriveSetSettings.cs
  48. 0 24
      RackPeek/Commands/Desktops/Gpus/DesktopGpuAddCommand.cs
  49. 0 19
      RackPeek/Commands/Desktops/Gpus/DesktopGpuAddSettings.cs
  50. 0 24
      RackPeek/Commands/Desktops/Gpus/DesktopGpuRemoveCommand.cs
  51. 0 15
      RackPeek/Commands/Desktops/Gpus/DesktopGpuRemoveSettings.cs
  52. 0 24
      RackPeek/Commands/Desktops/Gpus/DesktopGpuSetCommand.cs
  53. 0 23
      RackPeek/Commands/Desktops/Gpus/DesktopGpuSetSettings.cs
  54. 0 24
      RackPeek/Commands/Desktops/Nics/DesktopNicAddCommand.cs
  55. 0 23
      RackPeek/Commands/Desktops/Nics/DesktopNicAddSettings.cs
  56. 0 24
      RackPeek/Commands/Desktops/Nics/DesktopNicRemoveCommand.cs
  57. 0 15
      RackPeek/Commands/Desktops/Nics/DesktopNicRemoveSettings.cs
  58. 0 24
      RackPeek/Commands/Desktops/Nics/DesktopNicSetCommand.cs
  59. 0 27
      RackPeek/Commands/Desktops/Nics/DesktopNicSetSettings.cs
  60. 0 32
      RackPeek/Commands/Firewalls/FirewallAddCommand.cs
  61. 0 8
      RackPeek/Commands/Firewalls/FirewallCommands.cs
  62. 0 25
      RackPeek/Commands/Firewalls/FirewallDeleteCommand.cs
  63. 0 41
      RackPeek/Commands/Firewalls/FirewallDescribeCommand.cs
  64. 0 27
      RackPeek/Commands/Firewalls/FirewallGetByNameCommand.cs
  65. 0 49
      RackPeek/Commands/Firewalls/FirewallGetCommand.cs
  66. 0 51
      RackPeek/Commands/Firewalls/FirewallReportCommand.cs
  67. 0 39
      RackPeek/Commands/Firewalls/FirewallSetCommand.cs
  68. 0 29
      RackPeek/Commands/Firewalls/Ports/FirewallPortAddCommand.cs
  69. 0 27
      RackPeek/Commands/Firewalls/Ports/FirewallPortRemoveCommand.cs
  70. 0 30
      RackPeek/Commands/Firewalls/Ports/FirewallPortUpdateCommand.cs
  71. 0 139
      RackPeek/Commands/GetTotalSummaryCommand.cs
  72. 0 24
      RackPeek/Commands/Laptops/Cpus/LaptopCpuAddCommand.cs
  73. 0 23
      RackPeek/Commands/Laptops/Cpus/LaptopCpuAddSettings.cs
  74. 0 24
      RackPeek/Commands/Laptops/Cpus/LaptopCpuRemoveCommand.cs
  75. 0 15
      RackPeek/Commands/Laptops/Cpus/LaptopCpuRemoveSettings.cs
  76. 0 25
      RackPeek/Commands/Laptops/Cpus/LaptopCpuSetCommand.cs
  77. 0 27
      RackPeek/Commands/Laptops/Cpus/LaptopCpuSetSettings.cs
  78. 0 24
      RackPeek/Commands/Laptops/Drive/LaptopDriveAddCommand.cs
  79. 0 19
      RackPeek/Commands/Laptops/Drive/LaptopDriveAddSettings.cs
  80. 0 24
      RackPeek/Commands/Laptops/Drive/LaptopDriveRemoveCommand.cs
  81. 0 15
      RackPeek/Commands/Laptops/Drive/LaptopDriveRemoveSettings.cs
  82. 0 24
      RackPeek/Commands/Laptops/Drive/LaptopDriveSetCommand.cs
  83. 0 23
      RackPeek/Commands/Laptops/Drive/LaptopDriveSetSettings.cs
  84. 0 24
      RackPeek/Commands/Laptops/Gpus/LaptopGpuAddCommand.cs
  85. 0 19
      RackPeek/Commands/Laptops/Gpus/LaptopGpuAddSettings.cs
  86. 0 24
      RackPeek/Commands/Laptops/Gpus/LaptopGpuRemoveCommand.cs
  87. 0 15
      RackPeek/Commands/Laptops/Gpus/LaptopGpuRemoveSettings.cs
  88. 0 31
      RackPeek/Commands/Laptops/Gpus/LaptopGpuSetCommand.cs
  89. 0 23
      RackPeek/Commands/Laptops/Gpus/LaptopGpuSetSettings.cs
  90. 0 24
      RackPeek/Commands/Laptops/LaptopAddCommand.cs
  91. 0 8
      RackPeek/Commands/Laptops/LaptopCommands.cs
  92. 0 24
      RackPeek/Commands/Laptops/LaptopDeleteCommand.cs
  93. 0 33
      RackPeek/Commands/Laptops/LaptopDescribeCommand.cs
  94. 0 24
      RackPeek/Commands/Laptops/LaptopGetByNameCommand.cs
  95. 0 46
      RackPeek/Commands/Laptops/LaptopGetCommand.cs
  96. 0 49
      RackPeek/Commands/Laptops/LaptopReportCommand.cs
  97. 0 29
      RackPeek/Commands/Laptops/LaptopTreeCommand.cs
  98. 0 29
      RackPeek/Commands/Routers/Ports/RouterPortAddCommand.cs
  99. 0 27
      RackPeek/Commands/Routers/Ports/RouterPortRemoveCommand.cs
  100. 0 30
      RackPeek/Commands/Routers/Ports/RouterPortUpdateCommand.cs

BIN
.DS_Store


+ 1 - 0
.run/RackPeek.Web.Viewer_ https.run.xml

@@ -6,6 +6,7 @@
     <option name="USE_EXTERNAL_CONSOLE" value="0" />
     <option name="USE_MONO" value="0" />
     <option name="RUNTIME_ARGUMENTS" value="" />
+    <browser name="98ca6316-2f89-46d9-a9e5-fa9e2b0625b3" />
     <option name="GENERATE_APPLICATIONHOST_CONFIG" value="1" />
     <option name="SHOW_IIS_EXPRESS_OUTPUT" value="0" />
     <option name="SEND_DEBUG_REQUEST" value="1" />

+ 9 - 1
RackPeek.Domain/Persistence/Yaml/YamlResourceCollection.cs

@@ -25,7 +25,15 @@ public sealed class YamlResourceCollection(
     public async Task LoadAsync()
     {
         var loaded = await LoadFromFileAsync();
-        resourceCollection.Resources.Clear();
+        try
+        {
+            resourceCollection.Resources.Clear();
+        }
+        catch
+        {
+            // ignore
+        }
+
         resourceCollection.Resources.AddRange(loaded);
     }
 

+ 25 - 0
RackPeek.Domain/Persistence/YamlSystemRepository.cs

@@ -30,6 +30,31 @@ public class YamlSystemRepository(IResourceCollection resources) : ISystemReposi
         return Task.FromResult(resources.SystemResources);
     }
 
+    public Task<IReadOnlyList<SystemResource>> GetFilteredAsync(
+        string? typeFilter,
+        string? osFilter)
+    {
+        var query = resources.SystemResources.AsQueryable();
+
+        var type = Normalize(typeFilter);
+        var os = Normalize(osFilter);
+
+        if (type != null)
+            query = query.Where(x => x.Type != null && x.Type.Equals(type, StringComparison.CurrentCultureIgnoreCase));
+
+        if (os != null)
+            query = query.Where(x => x.Os != null && x.Os.Equals(os, StringComparison.CurrentCultureIgnoreCase));
+
+        var results = query.ToList();
+        return Task.FromResult<IReadOnlyList<SystemResource>>(results);
+    }
+
+    private static string? Normalize(string? value)
+    {
+        return string.IsNullOrWhiteSpace(value) ? null : value.Trim().ToLower();
+    }
+
+
     public Task<SystemResource?> GetByNameAsync(string name)
     {
         return Task.FromResult(resources.GetByName(name) as SystemResource);

+ 31 - 0
RackPeek.Domain/Resources/Hardware/AccessPoints/CloneAccessPointUseCase.cs

@@ -0,0 +1,31 @@
+using RackPeek.Domain.Helpers;
+using RackPeek.Domain.Resources.Models;
+
+namespace RackPeek.Domain.Resources.Hardware.Desktops;
+
+public class CloneAccessPointUseCase(IHardwareRepository repository, IResourceRepository resourceRepo) : IUseCase
+{
+    public async Task ExecuteAsync(string originalName, string cloneName)
+    {
+        originalName = Normalize.HardwareName(originalName);
+        ThrowIfInvalid.ResourceName(originalName);
+
+        cloneName = Normalize.HardwareName(cloneName);
+        ThrowIfInvalid.ResourceName(cloneName);
+        
+        var existingResourceKind = await resourceRepo.GetResourceKindAsync(cloneName);
+        if (!string.IsNullOrEmpty(existingResourceKind))
+            throw new ConflictException($"{existingResourceKind} resource '{cloneName}' already exists.");
+
+        var original = await repository.GetByNameAsync(originalName) as AccessPoint;
+        if (original == null)
+        {
+            throw new NotFoundException($"Resource '{originalName}' not found.");
+        }
+        
+        var clone = Clone.DeepClone(original);
+        clone.Name = cloneName;
+        
+        await repository.AddAsync(clone);
+    }
+}

+ 1 - 1
RackPeek.Domain/Resources/Hardware/Desktops/CloneDesktopUsecase.cs

@@ -17,7 +17,7 @@ public class CloneDesktopUseCase(IHardwareRepository repository, IResourceReposi
         if (!string.IsNullOrEmpty(existingResourceKind))
             throw new ConflictException($"{existingResourceKind} resource '{cloneName}' already exists.");
 
-        var original = await repository.GetByNameAsync(originalName) as Firewall;
+        var original = await repository.GetByNameAsync(originalName) as Desktop;
         if (original == null)
         {
             throw new NotFoundException($"Resource '{originalName}' not found.");

+ 2 - 0
RackPeek.Domain/Resources/SystemResources/ISystemRepository.cs

@@ -7,6 +7,8 @@ public interface ISystemRepository
     Task<Dictionary<string, int>> GetSystemOsCountAsync();
 
     Task<IReadOnlyList<SystemResource>> GetAllAsync();
+    Task<IReadOnlyList<SystemResource>> GetFilteredAsync(string? typeFilter, string? osFilter);
+
     Task AddAsync(SystemResource systemResource);
     Task UpdateAsync(SystemResource systemResource);
     Task DeleteAsync(string name);

+ 0 - 475
RackPeek.Web.Viewer/CliBootstrap.cs

@@ -1,475 +0,0 @@
-using System.ComponentModel.DataAnnotations;
-using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Commands;
-using RackPeek.Commands.AccessPoints;
-using RackPeek.Commands.Desktops;
-using RackPeek.Commands.Desktops.Cpus;
-using RackPeek.Commands.Desktops.Drive;
-using RackPeek.Commands.Desktops.Gpus;
-using RackPeek.Commands.Desktops.Nics;
-using RackPeek.Commands.Firewalls;
-using RackPeek.Commands.Firewalls.Ports;
-using RackPeek.Commands.Laptops;
-using RackPeek.Commands.Laptops.Cpus;
-using RackPeek.Commands.Laptops.Drive;
-using RackPeek.Commands.Laptops.Gpus;
-using RackPeek.Commands.Routers;
-using RackPeek.Commands.Routers.Ports;
-using RackPeek.Commands.Servers;
-using RackPeek.Commands.Servers.Cpus;
-using RackPeek.Commands.Servers.Drives;
-using RackPeek.Commands.Servers.Gpus;
-using RackPeek.Commands.Servers.Nics;
-using RackPeek.Commands.Services;
-using RackPeek.Commands.Switches;
-using RackPeek.Commands.Switches.Ports;
-using RackPeek.Commands.Systems;
-using RackPeek.Commands.Ups;
-using RackPeek.Domain;
-using RackPeek.Domain.Helpers;
-using RackPeek.Domain.Persistence;
-using RackPeek.Domain.Persistence.Yaml;
-using RackPeek.Domain.Resources;
-using RackPeek.Domain.Resources.Hardware;
-using RackPeek.Domain.Resources.Services;
-using RackPeek.Domain.Resources.SystemResources;
-using RackPeek.Yaml;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek;
-
-public static class CliBootstrap
-{
-    public static void BuildApp(CommandApp app)
-    {
-
-        // Spectre bootstrap
-        app.Configure(config =>
-        {
-            config.SetApplicationName("rpk");
-            config.ValidateExamples();
-
-            config.SetExceptionHandler(HandleException);
-
-            // Global summary
-            config.AddCommand<GetTotalSummaryCommand>("summary")
-                .WithDescription("Show a summarized report of all resources in the system.");
-
-            // ----------------------------
-            // Server commands (CRUD-style)
-            // ----------------------------
-            config.AddBranch("servers", server =>
-            {
-                server.SetDescription("Manage servers and their components.");
-
-                server.AddCommand<ServerReportCommand>("summary")
-                    .WithDescription("Show a summarized hardware report for all servers.");
-
-                server.AddCommand<ServerAddCommand>("add").WithDescription("Add a new server to the inventory.");
-
-                server.AddCommand<ServerGetByNameCommand>("get")
-                    .WithDescription("List all servers or retrieve a specific server by name.");
-
-                server.AddCommand<ServerDescribeCommand>("describe")
-                    .WithDescription("Display detailed information about a specific server.");
-
-                server.AddCommand<ServerSetCommand>("set").WithDescription("Update properties of an existing server.");
-
-                server.AddCommand<ServerDeleteCommand>("del").WithDescription("Delete a server from the inventory.");
-
-                server.AddCommand<ServerTreeCommand>("tree")
-                    .WithDescription("Display the dependency tree of a server.");
-
-                // Server CPUs
-                server.AddBranch("cpu", cpu =>
-                {
-                    cpu.SetDescription("Manage CPUs attached to a server.");
-
-                    cpu.AddCommand<ServerCpuAddCommand>("add").WithDescription("Add a CPU to a specific server.");
-
-                    cpu.AddCommand<ServerCpuSetCommand>("set").WithDescription("Update configuration of a server CPU.");
-
-                    cpu.AddCommand<ServerCpuRemoveCommand>("del").WithDescription("Remove a CPU from a server.");
-                });
-
-                // Server Drives
-                server.AddBranch("drive", drive =>
-                {
-                    drive.SetDescription("Manage drives attached to a server.");
-
-                    drive.AddCommand<ServerDriveAddCommand>("add").WithDescription("Add a storage drive to a server.");
-
-                    drive.AddCommand<ServerDriveUpdateCommand>("set")
-                        .WithDescription("Update properties of a server drive.");
-
-                    drive.AddCommand<ServerDriveRemoveCommand>("del").WithDescription("Remove a drive from a server.");
-                });
-
-                // Server GPUs
-                server.AddBranch("gpu", gpu =>
-                {
-                    gpu.SetDescription("Manage GPUs attached to a server.");
-
-                    gpu.AddCommand<ServerGpuAddCommand>("add").WithDescription("Add a GPU to a server.");
-
-                    gpu.AddCommand<ServerGpuUpdateCommand>("set").WithDescription("Update properties of a server GPU.");
-
-                    gpu.AddCommand<ServerGpuRemoveCommand>("del").WithDescription("Remove a GPU from a server.");
-                });
-
-                // Server NICs
-                server.AddBranch("nic", nic =>
-                {
-                    nic.SetDescription("Manage network interface cards (NICs) for a server.");
-
-                    nic.AddCommand<ServerNicAddCommand>("add").WithDescription("Add a NIC to a server.");
-
-                    nic.AddCommand<ServerNicUpdateCommand>("set").WithDescription("Update properties of a server NIC.");
-
-                    nic.AddCommand<ServerNicRemoveCommand>("del").WithDescription("Remove a NIC from a server.");
-                });
-            });
-
-            // ----------------------------
-            // Switch commands
-            // ----------------------------
-            config.AddBranch("switches", switches =>
-            {
-                switches.SetDescription("Manage network switches.");
-
-                switches.AddCommand<SwitchReportCommand>("summary")
-                    .WithDescription("Show a hardware report for all switches.");
-
-                switches.AddCommand<SwitchAddCommand>("add")
-                    .WithDescription("Add a new network switch to the inventory.");
-
-                switches.AddCommand<SwitchGetCommand>("list").WithDescription("List all switches in the system.");
-
-                switches.AddCommand<SwitchGetByNameCommand>("get")
-                    .WithDescription("Retrieve details of a specific switch by name.");
-
-                switches.AddCommand<SwitchDescribeCommand>("describe")
-                    .WithDescription("Show detailed information about a switch.");
-
-                switches.AddCommand<SwitchSetCommand>("set").WithDescription("Update properties of a switch.");
-
-                switches.AddCommand<SwitchDeleteCommand>("del").WithDescription("Delete a switch from the inventory.");
-                switches.AddBranch("port", port =>
-                {
-                    port.SetDescription("Manage ports on a network switch.");
-
-                    port.AddCommand<SwitchPortAddCommand>("add").WithDescription("Add a port to a switch.");
-
-                    port.AddCommand<SwitchPortUpdateCommand>("set").WithDescription("Update a switch port.");
-
-                    port.AddCommand<SwitchPortRemoveCommand>("del").WithDescription("Remove a port from a switch.");
-                });
-            });
-
-            // ----------------------------
-            // Routers commands
-            // ----------------------------
-            config.AddBranch("routers", routers =>
-            {
-                routers.SetDescription("Manage network routers.");
-
-                routers.AddCommand<RouterReportCommand>("summary")
-                    .WithDescription("Show a hardware report for all routers.");
-
-                routers.AddCommand<RouterAddCommand>("add")
-                    .WithDescription("Add a new network router to the inventory.");
-
-                routers.AddCommand<RouterGetCommand>("list").WithDescription("List all routers in the system.");
-
-                routers.AddCommand<RouterGetByNameCommand>("get")
-                    .WithDescription("Retrieve details of a specific router by name.");
-
-                routers.AddCommand<RouterDescribeCommand>("describe")
-                    .WithDescription("Show detailed information about a router.");
-
-                routers.AddCommand<RouterSetCommand>("set").WithDescription("Update properties of a router.");
-
-                routers.AddCommand<RouterDeleteCommand>("del").WithDescription("Delete a router from the inventory.");
-                routers.AddBranch("port", port =>
-                {
-                    port.SetDescription("Manage ports on a router.");
-
-                    port.AddCommand<RouterPortAddCommand>("add").WithDescription("Add a port to a router.");
-
-                    port.AddCommand<RouterPortUpdateCommand>("set").WithDescription("Update a router port.");
-
-                    port.AddCommand<RouterPortRemoveCommand>("del").WithDescription("Remove a port from a router.");
-                });
-            });
-
-            // ----------------------------
-            // Firewalls commands
-            // ----------------------------
-            config.AddBranch("firewalls", firewalls =>
-            {
-                firewalls.SetDescription("Manage firewalls.");
-
-                firewalls.AddCommand<FirewallReportCommand>("summary")
-                    .WithDescription("Show a hardware report for all firewalls.");
-
-                firewalls.AddCommand<FirewallAddCommand>("add").WithDescription("Add a new firewall to the inventory.");
-
-                firewalls.AddCommand<FirewallGetCommand>("list").WithDescription("List all firewalls in the system.");
-
-                firewalls.AddCommand<FirewallGetByNameCommand>("get")
-                    .WithDescription("Retrieve details of a specific firewall by name.");
-
-                firewalls.AddCommand<FirewallDescribeCommand>("describe")
-                    .WithDescription("Show detailed information about a firewall.");
-
-                firewalls.AddCommand<FirewallSetCommand>("set").WithDescription("Update properties of a firewall.");
-
-                firewalls.AddCommand<FirewallDeleteCommand>("del")
-                    .WithDescription("Delete a firewall from the inventory.");
-                firewalls.AddBranch("port", port =>
-                {
-                    port.SetDescription("Manage ports on a firewall.");
-
-                    port.AddCommand<FirewallPortAddCommand>("add").WithDescription("Add a port to a firewall.");
-
-                    port.AddCommand<FirewallPortUpdateCommand>("set").WithDescription("Update a firewall port.");
-
-                    port.AddCommand<FirewallPortRemoveCommand>("del").WithDescription("Remove a port from a firewall.");
-                });
-            });
-
-            // ----------------------------
-            // System commands
-            // ----------------------------
-            config.AddBranch("systems", system =>
-            {
-                system.SetDescription("Manage systems and their dependencies.");
-
-                system.AddCommand<SystemReportCommand>("summary")
-                    .WithDescription("Show a summary report for all systems.");
-
-                system.AddCommand<SystemAddCommand>("add").WithDescription("Add a new system to the inventory.");
-
-                system.AddCommand<SystemGetCommand>("list").WithDescription("List all systems.");
-
-                system.AddCommand<SystemGetByNameCommand>("get").WithDescription("Retrieve a system by name.");
-
-                system.AddCommand<SystemDescribeCommand>("describe")
-                    .WithDescription("Display detailed information about a system.");
-
-                system.AddCommand<SystemSetCommand>("set").WithDescription("Update properties of a system.");
-
-                system.AddCommand<SystemDeleteCommand>("del").WithDescription("Delete a system from the inventory.");
-
-                system.AddCommand<SystemTreeCommand>("tree")
-                    .WithDescription("Display the dependency tree for a system.");
-            });
-
-            // ----------------------------
-            // Access Points
-            // ----------------------------
-            config.AddBranch("accesspoints", ap =>
-            {
-                ap.SetDescription("Manage access points.");
-
-                ap.AddCommand<AccessPointReportCommand>("summary")
-                    .WithDescription("Show a hardware report for all access points.");
-
-                ap.AddCommand<AccessPointAddCommand>("add").WithDescription("Add a new access point.");
-
-                ap.AddCommand<AccessPointGetCommand>("list").WithDescription("List all access points.");
-
-                ap.AddCommand<AccessPointGetByNameCommand>("get").WithDescription("Retrieve an access point by name.");
-
-                ap.AddCommand<AccessPointDescribeCommand>("describe")
-                    .WithDescription("Show detailed information about an access point.");
-
-                ap.AddCommand<AccessPointSetCommand>("set").WithDescription("Update properties of an access point.");
-
-                ap.AddCommand<AccessPointDeleteCommand>("del").WithDescription("Delete an access point.");
-            });
-
-            // ----------------------------
-            // UPS units
-            // ----------------------------
-            config.AddBranch("ups", ups =>
-            {
-                ups.SetDescription("Manage UPS units.");
-
-                ups.AddCommand<UpsReportCommand>("summary")
-                    .WithDescription("Show a hardware report for all UPS units.");
-
-                ups.AddCommand<UpsAddCommand>("add").WithDescription("Add a new UPS unit.");
-
-                ups.AddCommand<UpsGetCommand>("list").WithDescription("List all UPS units.");
-
-                ups.AddCommand<UpsGetByNameCommand>("get").WithDescription("Retrieve a UPS unit by name.");
-
-                ups.AddCommand<UpsDescribeCommand>("describe")
-                    .WithDescription("Show detailed information about a UPS unit.");
-
-                ups.AddCommand<UpsSetCommand>("set").WithDescription("Update properties of a UPS unit.");
-
-                ups.AddCommand<UpsDeleteCommand>("del").WithDescription("Delete a UPS unit.");
-            });
-
-            // ----------------------------
-            // Desktops
-            // ----------------------------
-            config.AddBranch("desktops", desktops =>
-            {
-                desktops.SetDescription("Manage desktop computers and their components.");
-
-                // CRUD
-                desktops.AddCommand<DesktopAddCommand>("add").WithDescription("Add a new desktop.");
-                desktops.AddCommand<DesktopGetCommand>("list").WithDescription("List all desktops.");
-                desktops.AddCommand<DesktopGetByNameCommand>("get").WithDescription("Retrieve a desktop by name.");
-                desktops.AddCommand<DesktopDescribeCommand>("describe")
-                    .WithDescription("Show detailed information about a desktop.");
-                desktops.AddCommand<DesktopSetCommand>("set").WithDescription("Update properties of a desktop.");
-                desktops.AddCommand<DesktopDeleteCommand>("del")
-                    .WithDescription("Delete a desktop from the inventory.");
-                desktops.AddCommand<DesktopReportCommand>("summary")
-                    .WithDescription("Show a summarized hardware report for all desktops.");
-                desktops.AddCommand<DesktopTreeCommand>("tree")
-                    .WithDescription("Display the dependency tree for a desktop.");
-
-                // CPU
-                desktops.AddBranch("cpu", cpu =>
-                {
-                    cpu.SetDescription("Manage CPUs attached to desktops.");
-                    cpu.AddCommand<DesktopCpuAddCommand>("add").WithDescription("Add a CPU to a desktop.");
-                    cpu.AddCommand<DesktopCpuSetCommand>("set").WithDescription("Update a desktop CPU.");
-                    cpu.AddCommand<DesktopCpuRemoveCommand>("del").WithDescription("Remove a CPU from a desktop.");
-                });
-
-                // Drives
-                desktops.AddBranch("drive", drive =>
-                {
-                    drive.SetDescription("Manage storage drives attached to desktops.");
-                    drive.AddCommand<DesktopDriveAddCommand>("add").WithDescription("Add a drive to a desktop.");
-                    drive.AddCommand<DesktopDriveSetCommand>("set").WithDescription("Update a desktop drive.");
-                    drive.AddCommand<DesktopDriveRemoveCommand>("del")
-                        .WithDescription("Remove a drive from a desktop.");
-                });
-
-                // GPUs
-                desktops.AddBranch("gpu", gpu =>
-                {
-                    gpu.SetDescription("Manage GPUs attached to desktops.");
-                    gpu.AddCommand<DesktopGpuAddCommand>("add").WithDescription("Add a GPU to a desktop.");
-                    gpu.AddCommand<DesktopGpuSetCommand>("set").WithDescription("Update a desktop GPU.");
-                    gpu.AddCommand<DesktopGpuRemoveCommand>("del").WithDescription("Remove a GPU from a desktop.");
-                });
-
-                // NICs
-                desktops.AddBranch("nic", nic =>
-                {
-                    nic.SetDescription("Manage network interface cards (NICs) for desktops.");
-                    nic.AddCommand<DesktopNicAddCommand>("add").WithDescription("Add a NIC to a desktop.");
-                    nic.AddCommand<DesktopNicSetCommand>("set").WithDescription("Update a desktop NIC.");
-                    nic.AddCommand<DesktopNicRemoveCommand>("del").WithDescription("Remove a NIC from a desktop.");
-                });
-            });
-
-            // ----------------------------
-            // Laptops
-            // ----------------------------
-            config.AddBranch("Laptops", Laptops =>
-            {
-                Laptops.SetDescription("Manage Laptop computers and their components.");
-
-                // CRUD
-                Laptops.AddCommand<LaptopAddCommand>("add").WithDescription("Add a new Laptop.");
-                Laptops.AddCommand<LaptopGetCommand>("list").WithDescription("List all Laptops.");
-                Laptops.AddCommand<LaptopGetByNameCommand>("get").WithDescription("Retrieve a Laptop by name.");
-                Laptops.AddCommand<LaptopDescribeCommand>("describe")
-                    .WithDescription("Show detailed information about a Laptop.");
-                Laptops.AddCommand<LaptopDeleteCommand>("del").WithDescription("Delete a Laptop from the inventory.");
-                Laptops.AddCommand<LaptopReportCommand>("summary")
-                    .WithDescription("Show a summarized hardware report for all Laptops.");
-                Laptops.AddCommand<LaptopTreeCommand>("tree")
-                    .WithDescription("Display the dependency tree for a Laptop.");
-
-                // CPU
-                Laptops.AddBranch("cpu", cpu =>
-                {
-                    cpu.SetDescription("Manage CPUs attached to Laptops.");
-                    cpu.AddCommand<LaptopCpuAddCommand>("add").WithDescription("Add a CPU to a Laptop.");
-                    cpu.AddCommand<LaptopCpuSetCommand>("set").WithDescription("Update a Laptop CPU.");
-                    cpu.AddCommand<LaptopCpuRemoveCommand>("del").WithDescription("Remove a CPU from a Laptop.");
-                });
-
-                // Drives
-                Laptops.AddBranch("drive", drive =>
-                {
-                    drive.SetDescription("Manage storage drives attached to Laptops.");
-                    drive.AddCommand<LaptopDriveAddCommand>("add").WithDescription("Add a drive to a Laptop.");
-                    drive.AddCommand<LaptopDriveSetCommand>("set").WithDescription("Update a Laptop drive.");
-                    drive.AddCommand<LaptopDriveRemoveCommand>("del").WithDescription("Remove a drive from a Laptop.");
-                });
-
-                // GPUs
-                Laptops.AddBranch("gpu", gpu =>
-                {
-                    gpu.SetDescription("Manage GPUs attached to Laptops.");
-                    gpu.AddCommand<LaptopGpuAddCommand>("add").WithDescription("Add a GPU to a Laptop.");
-                    gpu.AddCommand<LaptopGpuSetCommand>("set").WithDescription("Update a Laptop GPU.");
-                    gpu.AddCommand<LaptopGpuRemoveCommand>("del").WithDescription("Remove a GPU from a Laptop.");
-                });
-            });
-
-            // ----------------------------
-            // Services
-            // ----------------------------
-            config.AddBranch("services", service =>
-            {
-                service.SetDescription("Manage services and their configurations.");
-
-                service.AddCommand<ServiceReportCommand>("summary")
-                    .WithDescription("Show a summary report for all services.");
-
-                service.AddCommand<ServiceAddCommand>("add").WithDescription("Add a new service.");
-
-                service.AddCommand<ServiceGetCommand>("list").WithDescription("List all services.");
-
-                service.AddCommand<ServiceGetByNameCommand>("get").WithDescription("Retrieve a service by name.");
-
-                service.AddCommand<ServiceDescribeCommand>("describe")
-                    .WithDescription("Show detailed information about a service.");
-
-                service.AddCommand<ServiceSetCommand>("set").WithDescription("Update properties of a service.");
-
-                service.AddCommand<ServiceDeleteCommand>("del").WithDescription("Delete a service.");
-
-                service.AddCommand<ServiceSubnetsCommand>("subnets")
-                    .WithDescription("List subnets associated with a service, optionally filtered by CIDR.");
-            });
-        });
-    }
-
-    private static int HandleException(Exception ex, ITypeResolver? arg2)
-    {
-        switch (ex)
-        {
-            case ValidationException ve:
-                AnsiConsole.MarkupLine($"[yellow]Validation error:[/] {ve.Message}");
-                return 2;
-
-            case ConflictException ce:
-                AnsiConsole.MarkupLine($"[red]Conflict:[/] {ce.Message}");
-                return 3;
-
-            case NotFoundException ne:
-                AnsiConsole.MarkupLine($"[red]Not found:[/] {ne.Message}");
-                return 4;
-
-            default:
-                AnsiConsole.MarkupLine("[red]Unexpected error occurred.[/]");
-                AnsiConsole.WriteException(ex, ExceptionFormats.ShortenEverything);
-                return 99;
-        }
-    }
-}

+ 8 - 4
RackPeek.Web.Viewer/Pages/Home.razor

@@ -94,8 +94,10 @@
                                 <li class="text-zinc-400">Types</li>
                                 @foreach (var (type, count) in _system.SystemsByType.OrderByDescending(x => x.Value))
                                 {
-                                    <li class="text-zinc-500">
-                                        └─ @type (@count)
+                                    <li class="text-zinc-500 hover:text-emerald-300">
+                                        <NavLink href="@($"systems/list?type={type}")" class="block">
+                                            └─ @type (@count)
+                                        </NavLink>
                                     </li>
                                 }
                             </ul>
@@ -107,8 +109,10 @@
                                 <li class="text-zinc-400">Operating Systems</li>
                                 @foreach (var (os, count) in _system.SystemsByOs.OrderByDescending(x => x.Value))
                                 {
-                                    <li class="text-zinc-500">
-                                        └─ @os (@count)
+                                    <li class="text-zinc-500 hover:text-emerald-300">
+                                        <NavLink href="@($"systems/list?os={os}")" class="block">
+                                            └─ @os (@count)
+                                        </NavLink>
                                     </li>
                                 }
                             </ul>

+ 4 - 4
RackPeek.Web.Viewer/Program.cs

@@ -29,7 +29,7 @@ public class Program
         builder.Services.AddSingleton(resources);
         builder.Services.AddScoped<IResourceCollection>(sp =>
             new YamlResourceCollection(
-                "config.yaml",
+                "config/config.yaml",
                 sp.GetRequiredService<ITextFileStore>(),
                 sp.GetRequiredService<ResourceCollection>()));
         
@@ -37,9 +37,9 @@ public class Program
         services.AddScoped<ISystemRepository, YamlSystemRepository>();
         services.AddScoped<IServiceRepository, YamlServiceRepository>();
         services.AddScoped<IResourceRepository, YamlResourceRepository>();
-        
-        var consoleEmulator = new ConsoleEmulator(services);
-        builder.Services.AddScoped<IConsoleEmulator>(_ => consoleEmulator);
+
+        builder.Services.AddCommands();
+        builder.Services.AddScoped<IConsoleEmulator, ConsoleEmulator>();
         
         builder.Services.AddUseCases();
         

+ 0 - 513
RackPeek.Web.Viewer/wwwroot/config.yaml

@@ -1,513 +0,0 @@
-resources:
-  # ------------------------
-  # Servers
-  # ------------------------
-  - kind: Server
-    name: proxmox-node01
-    cpus:
-      - model: AMD EPYC 7302P
-        cores: 16
-        threads: 32
-    ram:
-      size: 128gb
-      mts: 3200
-    drives:
-      - type: ssd
-        size: 1tb
-      - type: ssd
-        size: 1tb
-    nics:
-      - type: rj45
-        speed: 1gb
-        ports: 2
-      - type: sfp+
-        speed: 10gb
-        ports: 2
-    ipmi: true
-
-  - kind: Server
-    name: proxmox-node02
-    cpus:
-      - model: Intel Xeon Silver 4210
-        cores: 10
-        threads: 20
-    ram:
-      size: 96gb
-      mts: 2666
-    drives:
-      - type: ssd
-        size: 1tb
-      - type: hdd
-        size: 4tb
-    nics:
-      - type: rj45
-        speed: 1gb
-        ports: 2
-      - type: sfp+
-        speed: 10gb
-        ports: 1
-    ipmi: true
-
-  - kind: Server
-    name: truenas-storage
-    cpus:
-      - model: Intel Xeon E-2236
-        cores: 6
-        threads: 12
-    ram:
-      size: 64gb
-      mts: 2666
-    drives:
-      - type: hdd
-        size: 8tb
-      - type: hdd
-        size: 8tb
-      - type: hdd
-        size: 8tb
-      - type: hdd
-        size: 8tb
-    nics:
-      - type: rj45
-        speed: 1gb
-        ports: 1
-      - type: sfp+
-        speed: 10gb
-        ports: 1
-    ipmi: true
-
-  # ------------------------
-  # Network
-  # ------------------------
-  - kind: Firewall
-    name: pfsense-fw
-    model: Netgate-6100
-    ports:
-      - type: rj45
-        speed: 1gb
-        count: 4
-      - type: sfp+
-        speed: 10gb
-        count: 2
-    managed: true
-    poe: false
-
-  - kind: Router
-    name: core-router
-    model: Ubiquiti-ER-4
-    ports:
-      - type: rj45
-        speed: 1gb
-        count: 4
-      - type: sfp
-        speed: 10gb
-        count: 1
-    managed: true
-    poe: false
-
-  - kind: Switch
-    name: core-switch
-    model: UniFi-USW-Enterprise-24
-    ports:
-      - type: rj45
-        speed: 1gb
-        count: 12
-      - type: rj45
-        speed: 2.5gb
-        count: 8
-      - type: sfp+
-        speed: 10gb
-        count: 4
-    managed: true
-    poe: true
-
-  - kind: Switch
-    name: access-switch
-    model: UniFi-USW-16-PoE
-    ports:
-      - type: rj45
-        speed: 1gb
-        count: 16
-      - type: sfp
-        speed: 1gb
-        count: 2
-    managed: true
-    poe: true
-
-  - kind: AccessPoint
-    name: lounge-ap
-    model: UniFi-U6-Pro
-    speed: 2.5gb
-
-  # ------------------------
-  # Power
-  # ------------------------
-  - kind: Ups
-    name: rack-ups
-    model: APC-SmartUPS-2200
-    va: 2200
-
-  # ------------------------
-  # Desktops
-  # ------------------------
-  - kind: Desktop
-    name: workstation-linux
-    cpus:
-      - model: AMD Ryzen 9 5900X
-        cores: 12
-        threads: 24
-    ram:
-      size: 64gb
-      mts: 3600
-    drives:
-      - type: ssd
-        size: 1tb
-      - type: ssd
-        size: 2tb
-    nics:
-      - type: rj45
-        speed: 1gb
-        ports: 1
-    gpus:
-      - model: NVIDIA RTX 3080
-        vram: 10gb
-
-  - kind: Desktop
-    name: gaming-pc
-    cpus:
-      - model: Intel Core i7-12700K
-        cores: 12
-        threads: 20
-    ram:
-      size: 32gb
-      mts: 3200
-    drives:
-      - type: ssd
-        size: 1tb
-    nics:
-      - type: rj45
-        speed: 1gb
-        ports: 1
-    gpus:
-      - model: NVIDIA RTX 3070
-        vram: 8gb
-
-  # ------------------------
-  # Laptop
-  # ------------------------
-  - kind: Laptop
-    name: dev-laptop
-    cpus:
-      - model: Intel Core i7-1260P
-        cores: 12
-        threads: 16
-    ram:
-      size: 32gb
-      mts: 5200
-    drives:
-      - type: ssd
-        size: 1tb
-  # --------------------------------------------------
-  # Smart Home
-  # --------------------------------------------------
-  - kind: Service
-    name: home-assistant
-    network:
-      ip: 192.168.0.10
-      port: 8123
-      protocol: TCP
-      url: http://homeassistant.lan:8123
-    runsOn: vm-home-assistant
-
-  # --------------------------------------------------
-  # Media & Photos
-  # --------------------------------------------------
-  - kind: Service
-    name: plex
-    network:
-      ip: 192.168.0.20
-      port: 32400
-      protocol: TCP
-      url: http://plex.lan:32400
-    runsOn: vm-media-server
-
-  - kind: Service
-    name: jellyfin
-    network:
-      ip: 192.168.0.21
-      port: 8096
-      protocol: TCP
-      url: http://jellyfin.lan:8096
-    runsOn: vm-media-server
-
-  - kind: Service
-    name: immich
-    network:
-      ip: 192.168.0.22
-      port: 8080
-      protocol: TCP
-      url: http://immich.lan:8080
-    runsOn: vm-media-server
-
-  # --------------------------------------------------
-  # Storage & Backup
-  # --------------------------------------------------
-  - kind: Service
-    name: truenas-webui
-    network:
-      ip: 192.168.0.30
-      port: 443
-      protocol: TCP
-      url: https://truenas.lan
-    runsOn: truenas-core-os
-
-  - kind: Service
-    name: minio
-    network:
-      ip: 192.168.0.31
-      port: 9000
-      protocol: TCP
-      url: http://minio.lan:9000
-    runsOn: vm-media-server
-
-  # --------------------------------------------------
-  # Monitoring & Ops
-  # --------------------------------------------------
-  - kind: Service
-    name: prometheus
-    network:
-      ip: 192.168.0.40
-      port: 9090
-      protocol: TCP
-      url: http://prometheus.lan:9090
-    runsOn: vm-monitoring
-
-  - kind: Service
-    name: grafana
-    network:
-      ip: 192.168.0.41
-      port: 3000
-      protocol: TCP
-      url: http://grafana.lan:3000
-    runsOn: vm-monitoring
-
-  - kind: Service
-    name: alertmanager
-    network:
-      ip: 192.168.0.42
-      port: 9093
-      protocol: TCP
-      url: http://alertmanager.lan:9093
-    runsOn: vm-monitoring
-
-  # --------------------------------------------------
-  # Dev & Internal Tools
-  # --------------------------------------------------
-  - kind: Service
-    name: gitea
-    network:
-      ip: 192.168.0.50
-      port: 3001
-      protocol: TCP
-      url: http://git.lan:3001
-    runsOn: vm-monitoring
-
-  - kind: Service
-    name: docker-registry
-    network:
-      ip: 192.168.0.51
-      port: 5000
-      protocol: TCP
-      url: http://registry.lan:5000
-    runsOn: vm-monitoring
-
-  - kind: Service
-    name: portainer
-    network:
-      ip: 192.168.0.52
-      port: 9000
-      protocol: TCP
-      url: http://portainer.lan:9000
-    runsOn: vm-monitoring
-
-  # --------------------------------------------------
-  # Network Services
-  # --------------------------------------------------
-  - kind: Service
-    name: pihole
-    network:
-      ip: 192.168.0.53
-      port: 80
-      protocol: TCP
-      url: http://pihole.lan
-    runsOn: vm-monitoring
-
-  - kind: Service
-    name: firewall-webui
-    network:
-      ip: 192.168.0.1
-      port: 443
-      protocol: TCP
-      url: https://firewall.lan
-    runsOn: firewall-os
-
-  - kind: Service
-    name: router-webui
-    network:
-      ip: 192.168.0.254
-      port: 443
-      protocol: TCP
-      url: https://router.lan
-    runsOn: router-os
-  # --------------------------------------------------
-  # Hypervisors (Bare Metal)
-  # --------------------------------------------------
-  - kind: System
-    type: Hypervisor
-    name: proxmox-cluster-node01
-    os: proxmox
-    cores: 16
-    ram: 128gb
-    drives:
-      - size: 1tb
-      - size: 1tb
-    runsOn: proxmox-node01
-
-  - kind: System
-    type: Hypervisor
-    name: proxmox-cluster-node02
-    os: proxmox
-    cores: 10
-    ram: 96gb
-    drives:
-      - size: 1tb
-      - size: 4tb
-    runsOn: proxmox-node02
-
-  # --------------------------------------------------
-  # Storage OS (Bare Metal)
-  # --------------------------------------------------
-  - kind: System
-    type: Baremetal
-    name: truenas-core-os
-    os: truenas
-    cores: 6
-    ram: 64gb
-    drives:
-      - size: 8tb
-      - size: 8tb
-      - size: 8tb
-      - size: 8tb
-    runsOn: truenas-storage
-
-  # --------------------------------------------------
-  # IPMI / BMC Management
-  # --------------------------------------------------
-  - kind: System
-    type: Baremetal
-    name: ipmi-proxmox-node01
-    os: idrac
-    cores: 1
-    ram: 1gb
-    runsOn: proxmox-node01
-
-  - kind: System
-    type: Baremetal
-    name: ipmi-proxmox-node02
-    os: ipmi
-    cores: 1
-    ram: 1gb
-    runsOn: proxmox-node02
-
-  - kind: System
-    type: Baremetal
-    name: ipmi-truenas-storage
-    os: ipmi
-    cores: 1
-    ram: 1gb
-    runsOn: truenas-storage
-
-  # --------------------------------------------------
-  # Core Network Systems
-  # --------------------------------------------------
-  - kind: System
-    type: Baremetal
-    name: firewall-os
-    os: pfsense
-    cores: 4
-    ram: 8gb
-    drives:
-      - size: 32gb
-    runsOn: pfsense-fw
-
-  - kind: System
-    type: Baremetal
-    name: router-os
-    os: edgeos
-    cores: 4
-    ram: 4gb
-    drives:
-      - size: 4gb
-    runsOn: core-router
-
-  - kind: System
-    type: Baremetal
-    name: unifi-core-switch-os
-    os: unifi-os
-    cores: 2
-    ram: 2gb
-    drives:
-      - size: 8gb
-    runsOn: core-switch
-
-  - kind: System
-    type: Baremetal
-    name: unifi-access-switch-os
-    os: unifi-os
-    cores: 2
-    ram: 2gb
-    drives:
-      - size: 8gb
-    runsOn: access-switch
-
-  - kind: System
-    type: Baremetal
-    name: unifi-lounge-ap-os
-    os: unifi-firmware
-    cores: 2
-    ram: 1gb
-    drives:
-      - size: 4gb
-    runsOn: lounge-ap
-
-  # --------------------------------------------------
-  # Virtual Machines
-  # --------------------------------------------------
-  - kind: System
-    type: VM
-    name: vm-home-assistant
-    os: hassos
-    cores: 2
-    ram: 4gb
-    drives:
-      - size: 64gb
-    runsOn: proxmox-node01
-
-  - kind: System
-    type: VM
-    name: vm-media-server
-    os: ubuntu-22.04
-    cores: 4
-    ram: 8gb
-    drives:
-      - size: 500gb
-    runsOn: proxmox-node02
-
-  - kind: System
-    type: VM
-    name: vm-monitoring
-    os: debian-12
-    cores: 2
-    ram: 4gb
-    drives:
-      - size: 64gb
-    runsOn: proxmox-node01

BIN
RackPeek.Web/.DS_Store


+ 1 - 0
RackPeek.Web/Components/App.razor

@@ -8,6 +8,7 @@
     <ResourcePreloader/>
     <ImportMap/>
     <HeadOutlet @rendermode="InteractiveServer"/>
+    <script src="console.js"></script>
     <script src="tailwind.js"></script>
 </head>
 

+ 29 - 7
RackPeek.Web/Components/Routes.razor

@@ -3,11 +3,33 @@
 @using Shared.Rcl.AccessPoints
 @using Shared.Rcl.Layout
 @using Shared.Rcl.Servers
+@using RackPeek.Domain.Persistence
+
+@inject IResourceCollection Resources
+
+@if (!_ready)
+{
+    <p>Loading…</p>
+}
+else
+{
+    <Router AppAssembly="@typeof(App).Assembly"
+            AdditionalAssemblies="new[] { typeof(ServersListPage).Assembly }" 
+            NotFoundPage="typeof(NotFound)">
+        <Found Context="routeData">
+            <RouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)"/>
+        </Found>
+    </Router>
+}
+
+@code {
+    private bool _ready;
+
+    protected override async Task OnInitializedAsync()
+    {
+        await Resources.LoadAsync();
+        
+        _ready = true;
+    }
+}
 
-<Router AppAssembly="@typeof(App).Assembly"
-        AdditionalAssemblies="new[] { typeof(ServersListPage).Assembly }" 
-        NotFoundPage="typeof(NotFound)">
-<Found Context="routeData">
-        <RouteView RouteData="routeData" DefaultLayout="typeof(MainLayout)"/>
-    </Found>
-</Router>

+ 19 - 6
RackPeek.Web/Program.cs

@@ -36,16 +36,29 @@ public class Program
                 $"YAML directory not found: {yamlPath}"
             );
 
-        var collection = new YamlResourceCollection(Path.Combine(yamlDir, "config.yaml"), new PhysicalTextFileStore(), new ResourceCollection());
-        await collection.LoadAsync();
+        builder.Services.AddScoped<ITextFileStore, PhysicalTextFileStore>();
 
+        var resources = new ResourceCollection();
+        builder.Services.AddSingleton(resources);
+        
+        builder.Services.AddScoped<IResourceCollection>(sp =>
+            new YamlResourceCollection(
+                "./config/config.yaml",
+                sp.GetRequiredService<ITextFileStore>(),
+                sp.GetRequiredService<ResourceCollection>()));
+        
+        
         // Infrastructure
-        builder.Services.AddSingleton<IHardwareRepository>(_ => new YamlHardwareRepository(collection));
-        builder.Services.AddSingleton<ISystemRepository>(_ => new YamlSystemRepository(collection));
-        builder.Services.AddSingleton<IServiceRepository>(_ => new YamlServiceRepository(collection));
-        builder.Services.AddSingleton<IResourceRepository>(_ => new YamlResourceRepository(collection));
+        builder.Services.AddScoped<IHardwareRepository, YamlHardwareRepository>();
+        builder.Services.AddScoped<ISystemRepository, YamlSystemRepository>();
+        builder.Services.AddScoped<IServiceRepository, YamlServiceRepository>();
+        builder.Services.AddScoped<IResourceRepository, YamlResourceRepository>();
         
         builder.Services.AddUseCases();
+        builder.Services.AddCommands();
+        builder.Services.AddScoped<IConsoleEmulator, ConsoleEmulator>();
+
+        
 
         // Add services to the container.
         builder.Services.AddRazorComponents()

+ 0 - 1
RackPeek.Web/RackPeek.Web.csproj

@@ -9,7 +9,6 @@
     </PropertyGroup>
 
     <ItemGroup>
-        <ProjectReference Include="..\RackPeek\RackPeek.csproj"/>
         <ProjectReference Include="..\Shared.Rcl\Shared.Rcl.csproj" />
     </ItemGroup>
 

+ 9 - 0
RackPeek.Web/wwwroot/console.js

@@ -0,0 +1,9 @@
+window.consoleEmulatorScroll = (el) => {
+    if (el) el.scrollTop = el.scrollHeight;
+};
+
+window.consoleHasSelection = () => {
+    const sel = window.getSelection();
+    return sel && sel.toString().length > 0;
+};
+

BIN
RackPeek/.DS_Store


+ 0 - 11
RackPeek/Commands/AccessPoints/AccessCommands.cs

@@ -1,11 +0,0 @@
-using System.ComponentModel;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.AccessPoints;
-
-public class AccessPointNameSettings : CommandSettings
-{
-    [CommandArgument(0, "<name>")]
-    [Description("The access point name.")]
-    public string Name { get; set; } = default!;
-}

+ 0 - 33
RackPeek/Commands/AccessPoints/AccessPointAddCommand.cs

@@ -1,33 +0,0 @@
-using System.ComponentModel;
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.AccessPoints;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.AccessPoints;
-
-public class AccessPointAddSettings : CommandSettings
-{
-    [CommandArgument(0, "<name>")]
-    [Description("The access point name.")]
-    public string Name { get; set; } = default!;
-}
-
-public class AccessPointAddCommand(
-    IServiceProvider serviceProvider
-) : AsyncCommand<AccessPointAddSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        AccessPointAddSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = serviceProvider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<AddAccessPointUseCase>();
-
-        await useCase.ExecuteAsync(settings.Name);
-
-        AnsiConsole.MarkupLine($"[green]Access Point '{settings.Name}' added.[/]");
-        return 0;
-    }
-}

+ 0 - 25
RackPeek/Commands/AccessPoints/AccessPointDeleteCommand.cs

@@ -1,25 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.AccessPoints;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.AccessPoints;
-
-public class AccessPointDeleteCommand(
-    IServiceProvider serviceProvider
-) : AsyncCommand<AccessPointNameSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        AccessPointNameSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = serviceProvider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<DeleteAccessPointUseCase>();
-
-        await useCase.ExecuteAsync(settings.Name);
-
-        AnsiConsole.MarkupLine($"[green]Access Point '{settings.Name}' deleted.[/]");
-        return 0;
-    }
-}

+ 0 - 37
RackPeek/Commands/AccessPoints/AccessPointDescribeCommand.cs

@@ -1,37 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.AccessPoints;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.AccessPoints;
-
-public class AccessPointDescribeCommand(
-    IServiceProvider serviceProvider
-) : AsyncCommand<AccessPointNameSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        AccessPointNameSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = serviceProvider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<DescribeAccessPointUseCase>();
-
-        var ap = await useCase.ExecuteAsync(settings.Name);
-
-        var grid = new Grid()
-            .AddColumn(new GridColumn().NoWrap())
-            .AddColumn(new GridColumn().NoWrap());
-
-        grid.AddRow("Name:", ap.Name);
-        grid.AddRow("Model:", ap.Model ?? "Unknown");
-        grid.AddRow("Speed (Gbps):", ap.Speed?.ToString() ?? "Unknown");
-
-        AnsiConsole.Write(
-            new Panel(grid)
-                .Header("Access Point")
-                .Border(BoxBorder.Rounded));
-
-        return 0;
-    }
-}

+ 0 - 27
RackPeek/Commands/AccessPoints/AccessPointGetByNameCommand.cs

@@ -1,27 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.AccessPoints;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.AccessPoints;
-
-public class AccessPointGetByNameCommand(
-    IServiceProvider serviceProvider
-) : AsyncCommand<AccessPointNameSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        AccessPointNameSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = serviceProvider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<DescribeAccessPointUseCase>();
-
-        var ap = await useCase.ExecuteAsync(settings.Name);
-
-        AnsiConsole.MarkupLine(
-            $"[green]{ap.Name}[/]  Model: {ap.Model ?? "Unknown"}, Speed: {ap.Speed?.ToString() ?? "Unknown"}Gbps");
-
-        return 0;
-    }
-}

+ 0 - 44
RackPeek/Commands/AccessPoints/AccessPointGetCommand.cs

@@ -1,44 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.AccessPoints;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.AccessPoints;
-
-public class AccessPointGetCommand(
-    IServiceProvider serviceProvider
-) : AsyncCommand
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        CancellationToken cancellationToken)
-    {
-        using var scope = serviceProvider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<AccessPointHardwareReportUseCase>();
-
-        var report = await useCase.ExecuteAsync();
-
-        if (report.AccessPoints.Count == 0)
-        {
-            AnsiConsole.MarkupLine("[yellow]No access points found.[/]");
-            return 0;
-        }
-
-        var table = new Table()
-            .Border(TableBorder.Rounded)
-            .AddColumn("Name")
-            .AddColumn("Model")
-            .AddColumn("Speed (Gbps)");
-
-        foreach (var ap in report.AccessPoints)
-            table.AddRow(
-                ap.Name,
-                ap.Model,
-                ap.SpeedGb.ToString()
-            );
-
-
-        AnsiConsole.Write(table);
-        return 0;
-    }
-}

+ 0 - 43
RackPeek/Commands/AccessPoints/AccessPointReportCommand.cs

@@ -1,43 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-using RackPeek.Domain.Resources.Hardware.AccessPoints;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.AccessPoints;
-
-public class AccessPointReportCommand(
-    ILogger<AccessPointReportCommand> logger,
-    IServiceProvider serviceProvider
-) : AsyncCommand
-{
-    public override async Task<int> ExecuteAsync(CommandContext context, CancellationToken cancellationToken)
-    {
-        using var scope = serviceProvider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<AccessPointHardwareReportUseCase>();
-
-        var report = await useCase.ExecuteAsync();
-
-        if (report.AccessPoints.Count == 0)
-        {
-            AnsiConsole.MarkupLine("[yellow]No access points found.[/]");
-            return 0;
-        }
-
-        var table = new Table()
-            .Border(TableBorder.Rounded)
-            .AddColumn("Name")
-            .AddColumn("Model")
-            .AddColumn("Speed (Gbps)");
-
-        foreach (var ap in report.AccessPoints)
-            table.AddRow(
-                ap.Name,
-                ap.Model,
-                $"{ap.SpeedGb}"
-            );
-
-        AnsiConsole.Write(table);
-        return 0;
-    }
-}

+ 0 - 42
RackPeek/Commands/AccessPoints/AccessPointSetCommand.cs

@@ -1,42 +0,0 @@
-using System.ComponentModel;
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Commands.Servers;
-using RackPeek.Domain.Resources.Hardware.AccessPoints;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.AccessPoints;
-
-public class AccessPointSetSettings : ServerNameSettings
-{
-    [CommandOption("--model")]
-    [Description("The access point model name.")]
-    public string? Model { get; set; }
-
-    [CommandOption("--speed")]
-    [Description("The speed of the access point in Gb.")]
-    public double? Speed { get; set; }
-}
-
-public class AccessPointSetCommand(
-    IServiceProvider serviceProvider
-) : AsyncCommand<AccessPointSetSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        AccessPointSetSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = serviceProvider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<UpdateAccessPointUseCase>();
-
-        await useCase.ExecuteAsync(
-            settings.Name,
-            settings.Model,
-            settings.Speed
-        );
-
-        AnsiConsole.MarkupLine($"[green]Access Point '{settings.Name}' updated.[/]");
-        return 0;
-    }
-}

+ 0 - 24
RackPeek/Commands/Desktops/Cpus/DesktopCpuAddCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Desktops.Cpus;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Cpus;
-
-public class DesktopCpuAddCommand(IServiceProvider provider)
-    : AsyncCommand<DesktopCpuAddSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        DesktopCpuAddSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<AddDesktopCpuUseCase>();
-
-        await useCase.ExecuteAsync(settings.DesktopName, settings.Model, settings.Cores, settings.Threads);
-
-        AnsiConsole.MarkupLine($"[green]CPU added to desktop '{settings.DesktopName}'.[/]");
-        return 0;
-    }
-}

+ 0 - 23
RackPeek/Commands/Desktops/Cpus/DesktopCpuAddSettings.cs

@@ -1,23 +0,0 @@
-using System.ComponentModel;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Cpus;
-
-public class DesktopCpuAddSettings : CommandSettings
-{
-    [CommandArgument(0, "<desktop>")]
-    [Description("The desktop name.")]
-    public string DesktopName { get; set; } = default!;
-
-    [CommandOption("--model")]
-    [Description("The model name.")]
-    public string? Model { get; set; }
-
-    [CommandOption("--cores")]
-    [Description("The number of cpu cores.")]
-    public int? Cores { get; set; }
-
-    [CommandOption("--threads")]
-    [Description("The number of cpu threads.")]
-    public int? Threads { get; set; }
-}

+ 0 - 24
RackPeek/Commands/Desktops/Cpus/DesktopCpuRemoveCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Desktops.Cpus;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Cpus;
-
-public class DesktopCpuRemoveCommand(IServiceProvider provider)
-    : AsyncCommand<DesktopCpuRemoveSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        DesktopCpuRemoveSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<RemoveDesktopCpuUseCase>();
-
-        await useCase.ExecuteAsync(settings.DesktopName, settings.Index);
-
-        AnsiConsole.MarkupLine($"[green]CPU #{settings.Index} removed from desktop '{settings.DesktopName}'.[/]");
-        return 0;
-    }
-}

+ 0 - 15
RackPeek/Commands/Desktops/Cpus/DesktopCpuRemoveSettings.cs

@@ -1,15 +0,0 @@
-using System.ComponentModel;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Cpus;
-
-public class DesktopCpuRemoveSettings : CommandSettings
-{
-    [CommandArgument(0, "<desktop>")]
-    [Description("The name of the desktop.")]
-    public string DesktopName { get; set; } = default!;
-
-    [CommandArgument(1, "<index>")]
-    [Description("The index of the desktop cpu to remove.")]
-    public int Index { get; set; }
-}

+ 0 - 25
RackPeek/Commands/Desktops/Cpus/DesktopCpuSetCommand.cs

@@ -1,25 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Desktops.Cpus;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Cpus;
-
-public class DesktopCpuSetCommand(IServiceProvider provider)
-    : AsyncCommand<DesktopCpuSetSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        DesktopCpuSetSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<UpdateDesktopCpuUseCase>();
-
-        await useCase.ExecuteAsync(settings.DesktopName, settings.Index, settings.Model, settings.Cores,
-            settings.Threads);
-
-        AnsiConsole.MarkupLine($"[green]CPU #{settings.Index} updated on desktop '{settings.DesktopName}'.[/]");
-        return 0;
-    }
-}

+ 0 - 27
RackPeek/Commands/Desktops/Cpus/DesktopCpuSetSettings.cs

@@ -1,27 +0,0 @@
-using System.ComponentModel;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Cpus;
-
-public class DesktopCpuSetSettings : CommandSettings
-{
-    [CommandArgument(0, "<desktop>")]
-    [Description("The desktop name.")]
-    public string DesktopName { get; set; } = default!;
-
-    [CommandArgument(1, "<index>")]
-    [Description("The index of the desktop cpu.")]
-    public int Index { get; set; }
-
-    [CommandOption("--model")]
-    [Description("The cpu model.")]
-    public string? Model { get; set; }
-
-    [CommandOption("--cores")]
-    [Description("The number of cpu cores.")]
-    public int? Cores { get; set; }
-
-    [CommandOption("--threads")]
-    [Description("The number of cpu threads.")]
-    public int? Threads { get; set; }
-}

+ 0 - 24
RackPeek/Commands/Desktops/DesktopAddCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Desktops;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops;
-
-public class DesktopAddCommand(IServiceProvider provider)
-    : AsyncCommand<DesktopNameSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        DesktopNameSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<AddDesktopUseCase>();
-
-        await useCase.ExecuteAsync(settings.Name);
-
-        AnsiConsole.MarkupLine($"[green]Desktop '{settings.Name}' added.[/]");
-        return 0;
-    }
-}

+ 0 - 8
RackPeek/Commands/Desktops/DesktopCommands.cs

@@ -1,8 +0,0 @@
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops;
-
-public class DesktopNameSettings : CommandSettings
-{
-    [CommandArgument(0, "<name>")] public string Name { get; set; } = default!;
-}

+ 0 - 24
RackPeek/Commands/Desktops/DesktopDeleteCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Desktops;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops;
-
-public class DesktopDeleteCommand(IServiceProvider provider)
-    : AsyncCommand<DesktopNameSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        DesktopNameSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<DeleteDesktopUseCase>();
-
-        await useCase.ExecuteAsync(settings.Name);
-
-        AnsiConsole.MarkupLine($"[green]Desktop '{settings.Name}' deleted.[/]");
-        return 0;
-    }
-}

+ 0 - 35
RackPeek/Commands/Desktops/DesktopDescribeCommand.cs

@@ -1,35 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Desktops;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops;
-
-public class DesktopDescribeCommand(IServiceProvider provider)
-    : AsyncCommand<DesktopNameSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        DesktopNameSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<DescribeDesktopUseCase>();
-
-        var result = await useCase.ExecuteAsync(settings.Name);
-
-        var grid = new Grid().AddColumn().AddColumn();
-
-        grid.AddRow("Name:", result.Name);
-        grid.AddRow("Model:", result.Model ?? "Unknown");
-        grid.AddRow("CPUs:", result.CpuCount.ToString());
-        grid.AddRow("RAM:", result.RamSummary ?? "None");
-        grid.AddRow("Drives:", result.DriveCount.ToString());
-        grid.AddRow("NICs:", result.NicCount.ToString());
-        grid.AddRow("GPUs:", result.GpuCount.ToString());
-
-        AnsiConsole.Write(new Panel(grid).Header("Desktop").Border(BoxBorder.Rounded));
-
-        return 0;
-    }
-}

+ 0 - 24
RackPeek/Commands/Desktops/DesktopGetByNameCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Desktops;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops;
-
-public class DesktopGetByNameCommand(IServiceProvider provider)
-    : AsyncCommand<DesktopNameSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        DesktopNameSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<GetDesktopUseCase>();
-
-        var desktop = await useCase.ExecuteAsync(settings.Name);
-
-        AnsiConsole.MarkupLine($"[green]{desktop.Name}[/] (Model: {desktop.Model ?? "Unknown"})");
-        return 0;
-    }
-}

+ 0 - 50
RackPeek/Commands/Desktops/DesktopGetCommand.cs

@@ -1,50 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Desktops;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops;
-
-public class DesktopGetCommand(IServiceProvider provider)
-    : AsyncCommand
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<GetDesktopsUseCase>();
-
-        var desktops = await useCase.ExecuteAsync();
-
-        if (desktops.Count == 0)
-        {
-            AnsiConsole.MarkupLine("[yellow]No desktops found.[/]");
-            return 0;
-        }
-
-        var table = new Table()
-            .Border(TableBorder.Rounded)
-            .AddColumn("Name")
-            .AddColumn("Model")
-            .AddColumn("CPUs")
-            .AddColumn("RAM")
-            .AddColumn("Drives")
-            .AddColumn("NICs")
-            .AddColumn("GPUs");
-
-        foreach (var d in desktops)
-            table.AddRow(
-                d.Name,
-                d.Model ?? "Unknown",
-                (d.Cpus?.Count ?? 0).ToString(),
-                d.Ram == null ? "None" : $"{d.Ram.Size}GB",
-                (d.Drives?.Count ?? 0).ToString(),
-                (d.Nics?.Count ?? 0).ToString(),
-                (d.Gpus?.Count ?? 0).ToString()
-            );
-
-        AnsiConsole.Write(table);
-        return 0;
-    }
-}

+ 0 - 51
RackPeek/Commands/Desktops/DesktopReportCommand.cs

@@ -1,51 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-using RackPeek.Domain.Resources.Hardware.Desktops;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops;
-
-public class DesktopReportCommand(
-    ILogger<DesktopReportCommand> logger,
-    IServiceProvider serviceProvider
-) : AsyncCommand
-{
-    public override async Task<int> ExecuteAsync(CommandContext context, CancellationToken cancellationToken)
-    {
-        using var scope = serviceProvider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<DesktopHardwareReportUseCase>();
-
-        var report = await useCase.ExecuteAsync();
-
-        if (report.Desktops.Count == 0)
-        {
-            AnsiConsole.MarkupLine("[yellow]No desktops found.[/]");
-            return 0;
-        }
-
-        var table = new Table()
-            .Border(TableBorder.Rounded)
-            .AddColumn("Name")
-            .AddColumn("CPU")
-            .AddColumn("C/T")
-            .AddColumn("RAM")
-            .AddColumn("Storage")
-            .AddColumn("NICs")
-            .AddColumn("GPU");
-
-        foreach (var d in report.Desktops)
-            table.AddRow(
-                d.Name,
-                d.CpuSummary,
-                $"{d.TotalCores}/{d.TotalThreads}",
-                $"{d.RamGb} GB",
-                $"{d.TotalStorageGb} GB (SSD {d.SsdStorageGb} / HDD {d.HddStorageGb})",
-                d.NicSummary,
-                d.GpuSummary
-            );
-
-        AnsiConsole.Write(table);
-        return 0;
-    }
-}

+ 0 - 29
RackPeek/Commands/Desktops/DesktopSetCommand.cs

@@ -1,29 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Desktops;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops;
-
-public class DesktopSetSettings : DesktopNameSettings
-{
-    [CommandOption("--model")] public string? Model { get; set; }
-}
-
-public class DesktopSetCommand(IServiceProvider provider)
-    : AsyncCommand<DesktopSetSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        DesktopSetSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<UpdateDesktopUseCase>();
-
-        await useCase.ExecuteAsync(settings.Name, settings.Model);
-
-        AnsiConsole.MarkupLine($"[green]Desktop '{settings.Name}' updated.[/]");
-        return 0;
-    }
-}

+ 0 - 29
RackPeek/Commands/Desktops/DesktopTreeCommand.cs

@@ -1,29 +0,0 @@
-using RackPeek.Domain.Resources.Hardware;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops;
-
-public sealed class DesktopTreeCommand(GetHardwareSystemTreeUseCase useCase)
-    : AsyncCommand<DesktopNameSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        DesktopNameSettings settings,
-        CancellationToken cancellationToken)
-    {
-        var tree = await useCase.ExecuteAsync(settings.Name);
-
-        var root = new Tree($"[bold]{tree.Hardware.Name}[/]");
-
-        foreach (var system in tree.Systems)
-        {
-            var systemNode = root.AddNode($"[green]System:[/] {system.System.Name}");
-            foreach (var service in system.Services)
-                systemNode.AddNode($"[green]Service:[/] {service.Name}");
-        }
-
-        AnsiConsole.Write(root);
-        return 0;
-    }
-}

+ 0 - 24
RackPeek/Commands/Desktops/Drive/DesktopDriveAddCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Desktops.Drives;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Drive;
-
-public class DesktopDriveAddCommand(IServiceProvider provider)
-    : AsyncCommand<DesktopDriveAddSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        DesktopDriveAddSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<AddDesktopDriveUseCase>();
-
-        await useCase.ExecuteAsync(settings.DesktopName, settings.Type, settings.Size);
-
-        AnsiConsole.MarkupLine($"[green]Drive added to desktop '{settings.DesktopName}'.[/]");
-        return 0;
-    }
-}

+ 0 - 19
RackPeek/Commands/Desktops/Drive/DesktopDriveAddSettings.cs

@@ -1,19 +0,0 @@
-using System.ComponentModel;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Drive;
-
-public class DesktopDriveAddSettings : CommandSettings
-{
-    [CommandArgument(0, "<desktop>")]
-    [Description("The name of the desktop.")]
-    public string DesktopName { get; set; } = default!;
-
-    [CommandOption("--type")]
-    [Description("The drive type e.g hdd / ssd.")]
-    public string? Type { get; set; }
-
-    [CommandOption("--size")]
-    [Description("The drive capacity in Gb.")]
-    public int? Size { get; set; }
-}

+ 0 - 24
RackPeek/Commands/Desktops/Drive/DesktopDriveRemoveCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Desktops.Drives;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Drive;
-
-public class DesktopDriveRemoveCommand(IServiceProvider provider)
-    : AsyncCommand<DesktopDriveRemoveSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        DesktopDriveRemoveSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<RemoveDesktopDriveUseCase>();
-
-        await useCase.ExecuteAsync(settings.DesktopName, settings.Index);
-
-        AnsiConsole.MarkupLine($"[green]Drive #{settings.Index} removed from desktop '{settings.DesktopName}'.[/]");
-        return 0;
-    }
-}

+ 0 - 15
RackPeek/Commands/Desktops/Drive/DesktopDriveRemoveSettings.cs

@@ -1,15 +0,0 @@
-using System.ComponentModel;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Drive;
-
-public class DesktopDriveRemoveSettings : CommandSettings
-{
-    [CommandArgument(0, "<desktop>")]
-    [Description("The name of the desktop.")]
-    public string DesktopName { get; set; } = default!;
-
-    [CommandArgument(1, "<index>")]
-    [Description("The index of the drive to remove.")]
-    public int Index { get; set; }
-}

+ 0 - 24
RackPeek/Commands/Desktops/Drive/DesktopDriveSetCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Desktops.Drives;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Drive;
-
-public class DesktopDriveSetCommand(IServiceProvider provider)
-    : AsyncCommand<DesktopDriveSetSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        DesktopDriveSetSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<UpdateDesktopDriveUseCase>();
-
-        await useCase.ExecuteAsync(settings.DesktopName, settings.Index, settings.Type, settings.Size);
-
-        AnsiConsole.MarkupLine($"[green]Drive #{settings.Index} updated on desktop '{settings.DesktopName}'.[/]");
-        return 0;
-    }
-}

+ 0 - 23
RackPeek/Commands/Desktops/Drive/DesktopDriveSetSettings.cs

@@ -1,23 +0,0 @@
-using System.ComponentModel;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Drive;
-
-public class DesktopDriveSetSettings : CommandSettings
-{
-    [CommandArgument(0, "<desktop>")]
-    [Description("The desktop name.")]
-    public string DesktopName { get; set; } = default!;
-
-    [CommandArgument(1, "<index>")]
-    [Description("The drive index to update.")]
-    public int Index { get; set; }
-
-    [CommandOption("--type")]
-    [Description("The drive type e.g hdd / ssd.")]
-    public string? Type { get; set; }
-
-    [CommandOption("--size")]
-    [Description("The drive capacity in Gb.")]
-    public int? Size { get; set; }
-}

+ 0 - 24
RackPeek/Commands/Desktops/Gpus/DesktopGpuAddCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Desktops.Gpus;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Gpus;
-
-public class DesktopGpuAddCommand(IServiceProvider provider)
-    : AsyncCommand<DesktopGpuAddSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        DesktopGpuAddSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<AddDesktopGpuUseCase>();
-
-        await useCase.ExecuteAsync(settings.DesktopName, settings.Model, settings.Vram);
-
-        AnsiConsole.MarkupLine($"[green]GPU added to desktop '{settings.DesktopName}'.[/]");
-        return 0;
-    }
-}

+ 0 - 19
RackPeek/Commands/Desktops/Gpus/DesktopGpuAddSettings.cs

@@ -1,19 +0,0 @@
-using System.ComponentModel;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Gpus;
-
-public class DesktopGpuAddSettings : CommandSettings
-{
-    [CommandArgument(0, "<desktop>")]
-    [Description("The name of the desktop.")]
-    public string DesktopName { get; set; } = default!;
-
-    [CommandOption("--model")]
-    [Description("The Gpu model.")]
-    public string? Model { get; set; }
-
-    [CommandOption("--vram")]
-    [Description("The amount of gpu vram in Gb.")]
-    public int? Vram { get; set; }
-}

+ 0 - 24
RackPeek/Commands/Desktops/Gpus/DesktopGpuRemoveCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Desktops.Gpus;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Gpus;
-
-public class DesktopGpuRemoveCommand(IServiceProvider provider)
-    : AsyncCommand<DesktopGpuRemoveSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        DesktopGpuRemoveSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<RemoveDesktopGpuUseCase>();
-
-        await useCase.ExecuteAsync(settings.DesktopName, settings.Index);
-
-        AnsiConsole.MarkupLine($"[green]GPU #{settings.Index} removed from desktop '{settings.DesktopName}'.[/]");
-        return 0;
-    }
-}

+ 0 - 15
RackPeek/Commands/Desktops/Gpus/DesktopGpuRemoveSettings.cs

@@ -1,15 +0,0 @@
-using System.ComponentModel;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Gpus;
-
-public class DesktopGpuRemoveSettings : CommandSettings
-{
-    [CommandArgument(0, "<desktop>")]
-    [Description("The desktop name.")]
-    public string DesktopName { get; set; } = default!;
-
-    [CommandArgument(1, "<index>")]
-    [Description("The index of the Gpu to remove.")]
-    public int Index { get; set; }
-}

+ 0 - 24
RackPeek/Commands/Desktops/Gpus/DesktopGpuSetCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Desktops.Gpus;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Gpus;
-
-public class DesktopGpuSetCommand(IServiceProvider provider)
-    : AsyncCommand<DesktopGpuSetSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        DesktopGpuSetSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<UpdateDesktopGpuUseCase>();
-
-        await useCase.ExecuteAsync(settings.DesktopName, settings.Index, settings.Model, settings.Vram);
-
-        AnsiConsole.MarkupLine($"[green]GPU #{settings.Index} updated on desktop '{settings.DesktopName}'.[/]");
-        return 0;
-    }
-}

+ 0 - 23
RackPeek/Commands/Desktops/Gpus/DesktopGpuSetSettings.cs

@@ -1,23 +0,0 @@
-using System.ComponentModel;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Gpus;
-
-public class DesktopGpuSetSettings : CommandSettings
-{
-    [CommandArgument(0, "<desktop>")]
-    [Description("The desktop name.")]
-    public string DesktopName { get; set; } = default!;
-
-    [CommandArgument(1, "<index>")]
-    [Description("The index of the gpu to update.")]
-    public int Index { get; set; }
-
-    [CommandOption("--model")]
-    [Description("The gpu model name.")]
-    public string? Model { get; set; }
-
-    [CommandOption("--vram")]
-    [Description("The amount of gpu vram in Gb.")]
-    public int? Vram { get; set; }
-}

+ 0 - 24
RackPeek/Commands/Desktops/Nics/DesktopNicAddCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Desktops.Nics;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Nics;
-
-public class DesktopNicAddCommand(IServiceProvider provider)
-    : AsyncCommand<DesktopNicAddSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        DesktopNicAddSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<AddDesktopNicUseCase>();
-
-        await useCase.ExecuteAsync(settings.DesktopName, settings.Type, settings.Speed, settings.Ports);
-
-        AnsiConsole.MarkupLine($"[green]NIC added to desktop '{settings.DesktopName}'.[/]");
-        return 0;
-    }
-}

+ 0 - 23
RackPeek/Commands/Desktops/Nics/DesktopNicAddSettings.cs

@@ -1,23 +0,0 @@
-using System.ComponentModel;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Nics;
-
-public class DesktopNicAddSettings : CommandSettings
-{
-    [CommandArgument(0, "<desktop>")]
-    [Description("The desktop name.")]
-    public string DesktopName { get; set; } = default!;
-
-    [CommandOption("--type")]
-    [Description("The nic port type e.g rj45 / sfp+")]
-    public string? Type { get; set; }
-
-    [CommandOption("--speed")]
-    [Description("The port speed.")]
-    public int? Speed { get; set; }
-
-    [CommandOption("--ports")]
-    [Description("The number of ports.")]
-    public int? Ports { get; set; }
-}

+ 0 - 24
RackPeek/Commands/Desktops/Nics/DesktopNicRemoveCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Desktops.Nics;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Nics;
-
-public class DesktopNicRemoveCommand(IServiceProvider provider)
-    : AsyncCommand<DesktopNicRemoveSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        DesktopNicRemoveSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<RemoveDesktopNicUseCase>();
-
-        await useCase.ExecuteAsync(settings.DesktopName, settings.Index);
-
-        AnsiConsole.MarkupLine($"[green]NIC #{settings.Index} removed from desktop '{settings.DesktopName}'.[/]");
-        return 0;
-    }
-}

+ 0 - 15
RackPeek/Commands/Desktops/Nics/DesktopNicRemoveSettings.cs

@@ -1,15 +0,0 @@
-using System.ComponentModel;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Nics;
-
-public class DesktopNicRemoveSettings : CommandSettings
-{
-    [CommandArgument(0, "<desktop>")]
-    [Description("The desktop name.")]
-    public string DesktopName { get; set; } = default!;
-
-    [CommandArgument(1, "<index>")]
-    [Description("The index of the nic to remove.")]
-    public int Index { get; set; }
-}

+ 0 - 24
RackPeek/Commands/Desktops/Nics/DesktopNicSetCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Desktops.Nics;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Nics;
-
-public class DesktopNicSetCommand(IServiceProvider provider)
-    : AsyncCommand<DesktopNicSetSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        DesktopNicSetSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<UpdateDesktopNicUseCase>();
-
-        await useCase.ExecuteAsync(settings.DesktopName, settings.Index, settings.Type, settings.Speed, settings.Ports);
-
-        AnsiConsole.MarkupLine($"[green]NIC #{settings.Index} updated on desktop '{settings.DesktopName}'.[/]");
-        return 0;
-    }
-}

+ 0 - 27
RackPeek/Commands/Desktops/Nics/DesktopNicSetSettings.cs

@@ -1,27 +0,0 @@
-using System.ComponentModel;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Desktops.Nics;
-
-public class DesktopNicSetSettings : CommandSettings
-{
-    [CommandArgument(0, "<desktop>")]
-    [Description("The desktop name.")]
-    public string DesktopName { get; set; } = default!;
-
-    [CommandArgument(1, "<index>")]
-    [Description("The index of the nic to remove.")]
-    public int Index { get; set; }
-
-    [CommandOption("--type")]
-    [Description("The nic port type e.g rj45 / sfp+")]
-    public string? Type { get; set; }
-
-    [CommandOption("--speed")]
-    [Description("The speed of the nic in Gb/s.")]
-    public int? Speed { get; set; }
-
-    [CommandOption("--ports")]
-    [Description("The number of ports.")]
-    public int? Ports { get; set; }
-}

+ 0 - 32
RackPeek/Commands/Firewalls/FirewallAddCommand.cs

@@ -1,32 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Firewalls;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Firewalls;
-
-public class FirewallAddSettings : CommandSettings
-{
-    [CommandArgument(0, "<name>")] public string Name { get; set; } = default!;
-}
-
-public class FirewallAddCommand(
-    IServiceProvider serviceProvider
-) : AsyncCommand<FirewallAddSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        FirewallAddSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = serviceProvider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<AddFirewallUseCase>();
-
-        await useCase.ExecuteAsync(
-            settings.Name
-        );
-
-        AnsiConsole.MarkupLine($"[green]Firewall '{settings.Name}' added.[/]");
-        return 0;
-    }
-}

+ 0 - 8
RackPeek/Commands/Firewalls/FirewallCommands.cs

@@ -1,8 +0,0 @@
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Firewalls;
-
-public class FirewallNameSettings : CommandSettings
-{
-    [CommandArgument(0, "<name>")] public string Name { get; set; } = default!;
-}

+ 0 - 25
RackPeek/Commands/Firewalls/FirewallDeleteCommand.cs

@@ -1,25 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Firewalls;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Firewalls;
-
-public class FirewallDeleteCommand(
-    IServiceProvider serviceProvider
-) : AsyncCommand<FirewallNameSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        FirewallNameSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = serviceProvider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<DeleteFirewallUseCase>();
-
-        await useCase.ExecuteAsync(settings.Name);
-
-        AnsiConsole.MarkupLine($"[green]Firewall '{settings.Name}' deleted.[/]");
-        return 0;
-    }
-}

+ 0 - 41
RackPeek/Commands/Firewalls/FirewallDescribeCommand.cs

@@ -1,41 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Firewalls;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Firewalls;
-
-public class FirewallDescribeCommand(
-    IServiceProvider serviceProvider
-) : AsyncCommand<FirewallNameSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        FirewallNameSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = serviceProvider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<DescribeFirewallUseCase>();
-
-        var sw = await useCase.ExecuteAsync(settings.Name);
-
-        var grid = new Grid()
-            .AddColumn(new GridColumn().NoWrap())
-            .AddColumn(new GridColumn().NoWrap());
-
-        grid.AddRow("Name:", sw.Name);
-        grid.AddRow("Model:", sw.Model ?? "Unknown");
-        grid.AddRow("Managed:", sw.Managed.HasValue ? sw.Managed.Value ? "Yes" : "No" : "Unknown");
-        grid.AddRow("PoE:", sw.Poe.HasValue ? sw.Poe.Value ? "Yes" : "No" : "Unknown");
-        grid.AddRow("Total Ports:", sw.TotalPorts.ToString());
-        grid.AddRow("Total Speed (Gb):", sw.TotalSpeedGb.ToString());
-        grid.AddRow("Ports:", sw.PortSummary);
-
-        AnsiConsole.Write(
-            new Panel(grid)
-                .Header("Firewall")
-                .Border(BoxBorder.Rounded));
-
-        return 0;
-    }
-}

+ 0 - 27
RackPeek/Commands/Firewalls/FirewallGetByNameCommand.cs

@@ -1,27 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Firewalls;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Firewalls;
-
-public class FirewallGetByNameCommand(
-    IServiceProvider serviceProvider
-) : AsyncCommand<FirewallNameSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        FirewallNameSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = serviceProvider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<DescribeFirewallUseCase>();
-
-        var sw = await useCase.ExecuteAsync(settings.Name);
-
-        AnsiConsole.MarkupLine(
-            $"[green]{sw.Name}[/]  Model: {sw.Model ?? "Unknown"}, Managed: {(sw.Managed == true ? "Yes" : "No")}, PoE: {(sw.Poe == true ? "Yes" : "No")}");
-
-        return 0;
-    }
-}

+ 0 - 49
RackPeek/Commands/Firewalls/FirewallGetCommand.cs

@@ -1,49 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Firewalls;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Firewalls;
-
-public class FirewallGetCommand(
-    IServiceProvider serviceProvider
-) : AsyncCommand
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        CancellationToken cancellationToken)
-    {
-        using var scope = serviceProvider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<FirewallHardwareReportUseCase>();
-
-        var report = await useCase.ExecuteAsync();
-
-        if (report.Firewalls.Count == 0)
-        {
-            AnsiConsole.MarkupLine("[yellow]No Firewalls found.[/]");
-            return 0;
-        }
-
-        var table = new Table()
-            .Border(TableBorder.Rounded)
-            .AddColumn("Name")
-            .AddColumn("Model")
-            .AddColumn("Managed")
-            .AddColumn("PoE")
-            .AddColumn("Ports")
-            .AddColumn("Port Summary");
-
-        foreach (var s in report.Firewalls)
-            table.AddRow(
-                s.Name,
-                s.Model ?? "Unknown",
-                s.Managed ? "[green]yes[/]" : "[red]no[/]",
-                s.Poe ? "[green]yes[/]" : "[red]no[/]",
-                s.TotalPorts.ToString(),
-                s.PortSummary
-            );
-
-        AnsiConsole.Write(table);
-        return 0;
-    }
-}

+ 0 - 51
RackPeek/Commands/Firewalls/FirewallReportCommand.cs

@@ -1,51 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-using RackPeek.Domain.Resources.Hardware.Firewalls;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Firewalls;
-
-public class FirewallReportCommand(
-    ILogger<FirewallReportCommand> logger,
-    IServiceProvider serviceProvider
-) : AsyncCommand
-{
-    public override async Task<int> ExecuteAsync(CommandContext context, CancellationToken cancellationToken)
-    {
-        using var scope = serviceProvider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<FirewallHardwareReportUseCase>();
-
-        var report = await useCase.ExecuteAsync();
-
-        if (report.Firewalls.Count == 0)
-        {
-            AnsiConsole.MarkupLine("[yellow]No Firewalls found.[/]");
-            return 0;
-        }
-
-        var table = new Table()
-            .Border(TableBorder.Rounded)
-            .AddColumn("Name")
-            .AddColumn("Model")
-            .AddColumn("Managed")
-            .AddColumn("PoE")
-            .AddColumn("Ports")
-            .AddColumn("Max Speed")
-            .AddColumn("Port Summary");
-
-        foreach (var s in report.Firewalls)
-            table.AddRow(
-                s.Name,
-                s.Model,
-                s.Managed ? "[green]yes[/]" : "[red]no[/]",
-                s.Poe ? "[green]yes[/]" : "[red]no[/]",
-                s.TotalPorts.ToString(),
-                $"{s.MaxPortSpeedGb}G",
-                s.PortSummary
-            );
-
-        AnsiConsole.Write(table);
-        return 0;
-    }
-}

+ 0 - 39
RackPeek/Commands/Firewalls/FirewallSetCommand.cs

@@ -1,39 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Commands.Servers;
-using RackPeek.Domain.Resources.Hardware.Firewalls;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Firewalls;
-
-public class FirewallSetSettings : ServerNameSettings
-{
-    [CommandOption("--Model")] public string Model { get; set; } = default!;
-
-    [CommandOption("--managed")] public bool Managed { get; set; }
-
-    [CommandOption("--poe")] public bool Poe { get; set; }
-}
-
-public class FirewallSetCommand(
-    IServiceProvider serviceProvider
-) : AsyncCommand<FirewallSetSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        FirewallSetSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = serviceProvider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<UpdateFirewallUseCase>();
-
-        await useCase.ExecuteAsync(
-            settings.Name,
-            settings.Model,
-            settings.Managed,
-            settings.Poe);
-
-        AnsiConsole.MarkupLine($"[green]Firewall '{settings.Name}' updated.[/]");
-        return 0;
-    }
-}

+ 0 - 29
RackPeek/Commands/Firewalls/Ports/FirewallPortAddCommand.cs

@@ -1,29 +0,0 @@
-using Spectre.Console.Cli;
-using System.ComponentModel;
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Firewalls.Ports;
-using Spectre.Console;
-
-namespace RackPeek.Commands.Firewalls.Ports;
-
-public class FirewallPortAddSettings : FirewallNameSettings
-{
-    [CommandOption("--type")] public string? Type { get; set; }
-    [CommandOption("--speed")] public double? Speed { get; set; }
-    [CommandOption("--count")] public int? Count { get; set; }
-}
-
-public class FirewallPortAddCommand(IServiceProvider sp)
-    : AsyncCommand<FirewallPortAddSettings>
-{
-    public override async Task<int> ExecuteAsync(CommandContext ctx, FirewallPortAddSettings s, CancellationToken ct)
-    {
-        using var scope = sp.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<AddFirewallPortUseCase>();
-
-        await useCase.ExecuteAsync(s.Name, s.Type, s.Speed, s.Count);
-
-        AnsiConsole.MarkupLine($"[green]Port added to firewall '{s.Name}'.[/]");
-        return 0;
-    }
-}

+ 0 - 27
RackPeek/Commands/Firewalls/Ports/FirewallPortRemoveCommand.cs

@@ -1,27 +0,0 @@
-using Spectre.Console.Cli;
-using System.ComponentModel;
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Firewalls.Ports;
-using Spectre.Console;
-
-namespace RackPeek.Commands.Firewalls.Ports;
-
-public class FirewallPortRemoveSettings : FirewallNameSettings
-{
-    [CommandOption("--index <INDEX>")] public int Index { get; set; }
-}
-
-public class FirewallPortRemoveCommand(IServiceProvider sp)
-    : AsyncCommand<FirewallPortRemoveSettings>
-{
-    public override async Task<int> ExecuteAsync(CommandContext ctx, FirewallPortRemoveSettings s, CancellationToken ct)
-    {
-        using var scope = sp.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<RemoveFirewallPortUseCase>();
-
-        await useCase.ExecuteAsync(s.Name, s.Index);
-
-        AnsiConsole.MarkupLine($"[green]Port {s.Index} removed from firewall '{s.Name}'.[/]");
-        return 0;
-    }
-}

+ 0 - 30
RackPeek/Commands/Firewalls/Ports/FirewallPortUpdateCommand.cs

@@ -1,30 +0,0 @@
-using Spectre.Console.Cli;
-using System.ComponentModel;
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Firewalls.Ports;
-using Spectre.Console;
-
-namespace RackPeek.Commands.Firewalls.Ports;
-
-public class FirewallPortUpdateSettings : FirewallNameSettings
-{
-    [CommandOption("--index <INDEX>")] public int Index { get; set; }
-    [CommandOption("--type")] public string? Type { get; set; }
-    [CommandOption("--speed")] public double? Speed { get; set; }
-    [CommandOption("--count")] public int? Count { get; set; }
-}
-
-public class FirewallPortUpdateCommand(IServiceProvider sp)
-    : AsyncCommand<FirewallPortUpdateSettings>
-{
-    public override async Task<int> ExecuteAsync(CommandContext ctx, FirewallPortUpdateSettings s, CancellationToken ct)
-    {
-        using var scope = sp.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<UpdateFirewallPortUseCase>();
-
-        await useCase.ExecuteAsync(s.Name, s.Index, s.Type, s.Speed, s.Count);
-
-        AnsiConsole.MarkupLine($"[green]Port {s.Index} updated on firewall '{s.Name}'.[/]");
-        return 0;
-    }
-}

+ 0 - 139
RackPeek/Commands/GetTotalSummaryCommand.cs

@@ -1,139 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware;
-using RackPeek.Domain.Resources.Services.UseCases;
-using RackPeek.Domain.Resources.SystemResources.UseCases;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands;
-
-public class GetTotalSummaryCommand(IServiceProvider provider) : AsyncCommand
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-
-        var systemUseCase =
-            scope.ServiceProvider.GetRequiredService<GetSystemSummaryUseCase>();
-        var serviceUseCase =
-            scope.ServiceProvider.GetRequiredService<GetServiceSummaryUseCase>();
-        var hardwareUseCase =
-            scope.ServiceProvider.GetRequiredService<GetHardwareUseCaseSummary>();
-
-        // Execute all summaries in parallel
-        var systemTask = systemUseCase.ExecuteAsync();
-        var serviceTask = serviceUseCase.ExecuteAsync();
-        var hardwareTask = hardwareUseCase.ExecuteAsync();
-
-        await Task.WhenAll(systemTask, serviceTask, hardwareTask);
-
-        var systemSummary = systemTask.Result;
-        var serviceSummary = serviceTask.Result;
-        var hardwareSummary = hardwareTask.Result;
-
-        RenderSummaryTree(systemSummary, serviceSummary, hardwareSummary);
-
-        return 0;
-    }
-
-    private static void RenderSummaryTree(
-        SystemSummary systemSummary,
-        AllServicesSummary serviceSummary,
-        HardwareSummary hardwareSummary)
-    {
-        var tree = new Tree("[bold]Breakdown[/]");
-
-        var hardwareNode = tree.AddNode(
-            $"[bold]Hardware[/] ({hardwareSummary.TotalHardware})");
-
-        foreach (var (kind, count) in hardwareSummary.HardwareByKind.OrderByDescending(h => h.Value).ThenBy(h => h.Key))
-            hardwareNode.AddNode($"{kind}: {count}");
-
-        var systemsNode = tree.AddNode(
-            $"[bold]Systems[/] ({systemSummary.TotalSystems})");
-
-        if (systemSummary.SystemsByType.Count > 0)
-        {
-            var typesNode = systemsNode.AddNode("[bold]Types[/]");
-            foreach (var (type, count) in systemSummary.SystemsByType.OrderByDescending(h => h.Value)
-                         .ThenBy(h => h.Key))
-                typesNode.AddNode($"{type}: {count}");
-        }
-
-        if (systemSummary.SystemsByOs.Count > 0)
-        {
-            var osNode = systemsNode.AddNode("[bold]Operating Systems[/]");
-            foreach (var (os, count) in systemSummary.SystemsByOs.OrderByDescending(h => h.Value).ThenBy(h => h.Key))
-                osNode.AddNode($"{os}: {count}");
-        }
-
-        var servicesNode = tree.AddNode(
-            $"[bold]Services[/] ({serviceSummary.TotalServices})");
-
-        servicesNode.AddNode(
-            $"IP Addresses: {serviceSummary.TotalIpAddresses}");
-
-        AnsiConsole.Write(tree);
-    }
-
-    private static void RenderTotals(
-        SystemSummary systemSummary,
-        AllServicesSummary serviceSummary,
-        HardwareSummary hardwareSummary)
-    {
-        var grid = new Grid()
-            .AddColumn()
-            .AddColumn();
-
-        grid.AddRow("[bold]Systems[/]", systemSummary.TotalSystems.ToString());
-        grid.AddRow("[bold]Services[/]", serviceSummary.TotalServices.ToString());
-        grid.AddRow("[bold]Service IPs[/]", serviceSummary.TotalIpAddresses.ToString());
-        grid.AddRow("[bold]Hardware[/]", hardwareSummary.TotalHardware.ToString());
-
-        AnsiConsole.Write(
-            new Panel(grid)
-                .Header("[bold]Totals[/]")
-                .Border(BoxBorder.Rounded));
-    }
-
-    private static void RenderSystemBreakdown(SystemSummary systemSummary)
-    {
-        if (systemSummary.SystemsByType.Count == 0 &&
-            systemSummary.SystemsByOs.Count == 0)
-            return;
-
-        var table = new Table()
-            .Border(TableBorder.Rounded)
-            .Title("[bold]Systems Breakdown[/]")
-            .AddColumn("Category")
-            .AddColumn("Name")
-            .AddColumn("Count");
-
-        foreach (var (type, count) in systemSummary.SystemsByType)
-            table.AddRow("Type", type, count.ToString());
-
-        foreach (var (os, count) in systemSummary.SystemsByOs)
-            table.AddRow("OS", os, count.ToString());
-
-        AnsiConsole.Write(table);
-    }
-
-    private static void RenderHardwareBreakdown(HardwareSummary hardwareSummary)
-    {
-        if (hardwareSummary.HardwareByKind.Count == 0)
-            return;
-
-        var table = new Table()
-            .Border(TableBorder.Rounded)
-            .Title("[bold]Hardware Breakdown[/]")
-            .AddColumn("Kind")
-            .AddColumn("Count");
-
-        foreach (var (kind, count) in hardwareSummary.HardwareByKind)
-            table.AddRow(kind, count.ToString());
-
-        AnsiConsole.Write(table);
-    }
-}

+ 0 - 24
RackPeek/Commands/Laptops/Cpus/LaptopCpuAddCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Laptops.Cpus;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops.Cpus;
-
-public class LaptopCpuAddCommand(IServiceProvider provider)
-    : AsyncCommand<LaptopCpuAddSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        LaptopCpuAddSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<AddLaptopCpuUseCase>();
-
-        await useCase.ExecuteAsync(settings.LaptopName, settings.Model, settings.Cores, settings.Threads);
-
-        AnsiConsole.MarkupLine($"[green]CPU added to Laptop '{settings.LaptopName}'.[/]");
-        return 0;
-    }
-}

+ 0 - 23
RackPeek/Commands/Laptops/Cpus/LaptopCpuAddSettings.cs

@@ -1,23 +0,0 @@
-using System.ComponentModel;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops.Cpus;
-
-public class LaptopCpuAddSettings : CommandSettings
-{
-    [CommandArgument(0, "<Laptop>")]
-    [Description("The Laptop name.")]
-    public string LaptopName { get; set; } = default!;
-
-    [CommandOption("--model")]
-    [Description("The model name.")]
-    public string? Model { get; set; }
-
-    [CommandOption("--cores")]
-    [Description("The number of cpu cores.")]
-    public int? Cores { get; set; }
-
-    [CommandOption("--threads")]
-    [Description("The number of cpu threads.")]
-    public int? Threads { get; set; }
-}

+ 0 - 24
RackPeek/Commands/Laptops/Cpus/LaptopCpuRemoveCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Laptops.Cpus;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops.Cpus;
-
-public class LaptopCpuRemoveCommand(IServiceProvider provider)
-    : AsyncCommand<LaptopCpuRemoveSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        LaptopCpuRemoveSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<RemoveLaptopCpuUseCase>();
-
-        await useCase.ExecuteAsync(settings.LaptopName, settings.Index);
-
-        AnsiConsole.MarkupLine($"[green]CPU #{settings.Index} removed from Laptop '{settings.LaptopName}'.[/]");
-        return 0;
-    }
-}

+ 0 - 15
RackPeek/Commands/Laptops/Cpus/LaptopCpuRemoveSettings.cs

@@ -1,15 +0,0 @@
-using System.ComponentModel;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops.Cpus;
-
-public class LaptopCpuRemoveSettings : CommandSettings
-{
-    [CommandArgument(0, "<Laptop>")]
-    [Description("The name of the Laptop.")]
-    public string LaptopName { get; set; } = default!;
-
-    [CommandArgument(1, "<index>")]
-    [Description("The index of the Laptop cpu to remove.")]
-    public int Index { get; set; }
-}

+ 0 - 25
RackPeek/Commands/Laptops/Cpus/LaptopCpuSetCommand.cs

@@ -1,25 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Laptops.Cpus;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops.Cpus;
-
-public class LaptopCpuSetCommand(IServiceProvider provider)
-    : AsyncCommand<LaptopCpuSetSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        LaptopCpuSetSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<UpdateLaptopCpuUseCase>();
-
-        await useCase.ExecuteAsync(settings.LaptopName, settings.Index, settings.Model, settings.Cores,
-            settings.Threads);
-
-        AnsiConsole.MarkupLine($"[green]CPU #{settings.Index} updated on Laptop '{settings.LaptopName}'.[/]");
-        return 0;
-    }
-}

+ 0 - 27
RackPeek/Commands/Laptops/Cpus/LaptopCpuSetSettings.cs

@@ -1,27 +0,0 @@
-using System.ComponentModel;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops.Cpus;
-
-public class LaptopCpuSetSettings : CommandSettings
-{
-    [CommandArgument(0, "<Laptop>")]
-    [Description("The Laptop name.")]
-    public string LaptopName { get; set; } = default!;
-
-    [CommandArgument(1, "<index>")]
-    [Description("The index of the Laptop cpu.")]
-    public int Index { get; set; }
-
-    [CommandOption("--model")]
-    [Description("The cpu model.")]
-    public string? Model { get; set; }
-
-    [CommandOption("--cores")]
-    [Description("The number of cpu cores.")]
-    public int? Cores { get; set; }
-
-    [CommandOption("--threads")]
-    [Description("The number of cpu threads.")]
-    public int? Threads { get; set; }
-}

+ 0 - 24
RackPeek/Commands/Laptops/Drive/LaptopDriveAddCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Laptops.Drives;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops.Drive;
-
-public class LaptopDriveAddCommand(IServiceProvider provider)
-    : AsyncCommand<LaptopDriveAddSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        LaptopDriveAddSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<AddLaptopDriveUseCase>();
-
-        await useCase.ExecuteAsync(settings.LaptopName, settings.Type, settings.Size);
-
-        AnsiConsole.MarkupLine($"[green]Drive added to Laptop '{settings.LaptopName}'.[/]");
-        return 0;
-    }
-}

+ 0 - 19
RackPeek/Commands/Laptops/Drive/LaptopDriveAddSettings.cs

@@ -1,19 +0,0 @@
-using System.ComponentModel;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops.Drive;
-
-public class LaptopDriveAddSettings : CommandSettings
-{
-    [CommandArgument(0, "<Laptop>")]
-    [Description("The name of the Laptop.")]
-    public string LaptopName { get; set; } = default!;
-
-    [CommandOption("--type")]
-    [Description("The drive type e.g hdd / ssd.")]
-    public string? Type { get; set; }
-
-    [CommandOption("--size")]
-    [Description("The drive capacity in Gb.")]
-    public int? Size { get; set; }
-}

+ 0 - 24
RackPeek/Commands/Laptops/Drive/LaptopDriveRemoveCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Laptops.Drives;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops.Drive;
-
-public class LaptopDriveRemoveCommand(IServiceProvider provider)
-    : AsyncCommand<LaptopDriveRemoveSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        LaptopDriveRemoveSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<RemoveLaptopDriveUseCase>();
-
-        await useCase.ExecuteAsync(settings.LaptopName, settings.Index);
-
-        AnsiConsole.MarkupLine($"[green]Drive #{settings.Index} removed from Laptop '{settings.LaptopName}'.[/]");
-        return 0;
-    }
-}

+ 0 - 15
RackPeek/Commands/Laptops/Drive/LaptopDriveRemoveSettings.cs

@@ -1,15 +0,0 @@
-using System.ComponentModel;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops.Drive;
-
-public class LaptopDriveRemoveSettings : CommandSettings
-{
-    [CommandArgument(0, "<Laptop>")]
-    [Description("The name of the Laptop.")]
-    public string LaptopName { get; set; } = default!;
-
-    [CommandArgument(1, "<index>")]
-    [Description("The index of the drive to remove.")]
-    public int Index { get; set; }
-}

+ 0 - 24
RackPeek/Commands/Laptops/Drive/LaptopDriveSetCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Laptops.Drives;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops.Drive;
-
-public class LaptopDriveSetCommand(IServiceProvider provider)
-    : AsyncCommand<LaptopDriveSetSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        LaptopDriveSetSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<UpdateLaptopDriveUseCase>();
-
-        await useCase.ExecuteAsync(settings.LaptopName, settings.Index, settings.Type, settings.Size);
-
-        AnsiConsole.MarkupLine($"[green]Drive #{settings.Index} updated on Laptop '{settings.LaptopName}'.[/]");
-        return 0;
-    }
-}

+ 0 - 23
RackPeek/Commands/Laptops/Drive/LaptopDriveSetSettings.cs

@@ -1,23 +0,0 @@
-using System.ComponentModel;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops.Drive;
-
-public class LaptopDriveSetSettings : CommandSettings
-{
-    [CommandArgument(0, "<Laptop>")]
-    [Description("The Laptop name.")]
-    public string LaptopName { get; set; } = default!;
-
-    [CommandArgument(1, "<index>")]
-    [Description("The drive index to update.")]
-    public int Index { get; set; }
-
-    [CommandOption("--type")]
-    [Description("The drive type e.g hdd / ssd.")]
-    public string? Type { get; set; }
-
-    [CommandOption("--size")]
-    [Description("The drive capacity in Gb.")]
-    public int? Size { get; set; }
-}

+ 0 - 24
RackPeek/Commands/Laptops/Gpus/LaptopGpuAddCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Laptops.Gpus;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops.Gpus;
-
-public class LaptopGpuAddCommand(IServiceProvider provider)
-    : AsyncCommand<LaptopGpuAddSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        LaptopGpuAddSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<AddLaptopGpuUseCase>();
-
-        await useCase.ExecuteAsync(settings.LaptopName, settings.Model, settings.Vram);
-
-        AnsiConsole.MarkupLine($"[green]GPU added to Laptop '{settings.LaptopName}'.[/]");
-        return 0;
-    }
-}

+ 0 - 19
RackPeek/Commands/Laptops/Gpus/LaptopGpuAddSettings.cs

@@ -1,19 +0,0 @@
-using System.ComponentModel;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops.Gpus;
-
-public class LaptopGpuAddSettings : CommandSettings
-{
-    [CommandArgument(0, "<Laptop>")]
-    [Description("The name of the Laptop.")]
-    public string LaptopName { get; set; } = default!;
-
-    [CommandOption("--model")]
-    [Description("The Gpu model.")]
-    public string? Model { get; set; }
-
-    [CommandOption("--vram")]
-    [Description("The amount of gpu vram in Gb.")]
-    public int? Vram { get; set; }
-}

+ 0 - 24
RackPeek/Commands/Laptops/Gpus/LaptopGpuRemoveCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Laptops.Gpus;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops.Gpus;
-
-public class LaptopGpuRemoveCommand(IServiceProvider provider)
-    : AsyncCommand<LaptopGpuRemoveSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        LaptopGpuRemoveSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<RemoveLaptopGpuUseCase>();
-
-        await useCase.ExecuteAsync(settings.LaptopName, settings.Index);
-
-        AnsiConsole.MarkupLine($"[green]GPU #{settings.Index} removed from Laptop '{settings.LaptopName}'.[/]");
-        return 0;
-    }
-}

+ 0 - 15
RackPeek/Commands/Laptops/Gpus/LaptopGpuRemoveSettings.cs

@@ -1,15 +0,0 @@
-using System.ComponentModel;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops.Gpus;
-
-public class LaptopGpuRemoveSettings : CommandSettings
-{
-    [CommandArgument(0, "<Laptop>")]
-    [Description("The Laptop name.")]
-    public string LaptopName { get; set; } = default!;
-
-    [CommandArgument(1, "<index>")]
-    [Description("The index of the Gpu to remove.")]
-    public int Index { get; set; }
-}

+ 0 - 31
RackPeek/Commands/Laptops/Gpus/LaptopGpuSetCommand.cs

@@ -1,31 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Laptops.Gpus;
-using RackPeek.Domain.Resources.Models;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops.Gpus;
-
-public class LaptopGpuSetCommand(IServiceProvider provider)
-    : AsyncCommand<LaptopGpuSetSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        LaptopGpuSetSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<UpdateLaptopGpuUseCase>();
-
-        var gpu = new Gpu
-        {
-            Model = settings.Model,
-            Vram = settings.Vram
-        };
-
-        await useCase.ExecuteAsync(settings.LaptopName, settings.Index, settings.Model, settings.Vram);
-
-        AnsiConsole.MarkupLine($"[green]GPU #{settings.Index} updated on Laptop '{settings.LaptopName}'.[/]");
-        return 0;
-    }
-}

+ 0 - 23
RackPeek/Commands/Laptops/Gpus/LaptopGpuSetSettings.cs

@@ -1,23 +0,0 @@
-using System.ComponentModel;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops.Gpus;
-
-public class LaptopGpuSetSettings : CommandSettings
-{
-    [CommandArgument(0, "<Laptop>")]
-    [Description("The Laptop name.")]
-    public string LaptopName { get; set; } = default!;
-
-    [CommandArgument(1, "<index>")]
-    [Description("The index of the gpu to update.")]
-    public int Index { get; set; }
-
-    [CommandOption("--model")]
-    [Description("The gpu model name.")]
-    public string? Model { get; set; }
-
-    [CommandOption("--vram")]
-    [Description("The amount of gpu vram in Gb.")]
-    public int? Vram { get; set; }
-}

+ 0 - 24
RackPeek/Commands/Laptops/LaptopAddCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Laptops;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops;
-
-public class LaptopAddCommand(IServiceProvider provider)
-    : AsyncCommand<LaptopNameSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        LaptopNameSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<AddLaptopUseCase>();
-
-        await useCase.ExecuteAsync(settings.Name);
-
-        AnsiConsole.MarkupLine($"[green]Laptop '{settings.Name}' added.[/]");
-        return 0;
-    }
-}

+ 0 - 8
RackPeek/Commands/Laptops/LaptopCommands.cs

@@ -1,8 +0,0 @@
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops;
-
-public class LaptopNameSettings : CommandSettings
-{
-    [CommandArgument(0, "<name>")] public string Name { get; set; } = default!;
-}

+ 0 - 24
RackPeek/Commands/Laptops/LaptopDeleteCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Laptops;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops;
-
-public class LaptopDeleteCommand(IServiceProvider provider)
-    : AsyncCommand<LaptopNameSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        LaptopNameSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<DeleteLaptopUseCase>();
-
-        await useCase.ExecuteAsync(settings.Name);
-
-        AnsiConsole.MarkupLine($"[green]Laptop '{settings.Name}' deleted.[/]");
-        return 0;
-    }
-}

+ 0 - 33
RackPeek/Commands/Laptops/LaptopDescribeCommand.cs

@@ -1,33 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Laptops;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops;
-
-public class LaptopDescribeCommand(IServiceProvider provider)
-    : AsyncCommand<LaptopNameSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        LaptopNameSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<DescribeLaptopUseCase>();
-
-        var result = await useCase.ExecuteAsync(settings.Name);
-
-        var grid = new Grid().AddColumn().AddColumn();
-
-        grid.AddRow("Name:", result.Name);
-        grid.AddRow("CPUs:", result.CpuCount.ToString());
-        grid.AddRow("RAM:", result.RamSummary ?? "None");
-        grid.AddRow("Drives:", result.DriveCount.ToString());
-        grid.AddRow("GPUs:", result.GpuCount.ToString());
-
-        AnsiConsole.Write(new Panel(grid).Header("Laptop").Border(BoxBorder.Rounded));
-
-        return 0;
-    }
-}

+ 0 - 24
RackPeek/Commands/Laptops/LaptopGetByNameCommand.cs

@@ -1,24 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Laptops;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops;
-
-public class LaptopGetByNameCommand(IServiceProvider provider)
-    : AsyncCommand<LaptopNameSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        LaptopNameSettings settings,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<GetLaptopUseCase>();
-
-        var laptop = await useCase.ExecuteAsync(settings.Name);
-
-        AnsiConsole.MarkupLine($"[green]{laptop.Name}[/]");
-        return 0;
-    }
-}

+ 0 - 46
RackPeek/Commands/Laptops/LaptopGetCommand.cs

@@ -1,46 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Laptops;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops;
-
-public class LaptopGetCommand(IServiceProvider provider)
-    : AsyncCommand
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        CancellationToken cancellationToken)
-    {
-        using var scope = provider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<GetLaptopsUseCase>();
-
-        var laptops = await useCase.ExecuteAsync();
-
-        if (laptops.Count == 0)
-        {
-            AnsiConsole.MarkupLine("[yellow]No Laptops found.[/]");
-            return 0;
-        }
-
-        var table = new Table()
-            .Border(TableBorder.Rounded)
-            .AddColumn("Name")
-            .AddColumn("CPUs")
-            .AddColumn("RAM")
-            .AddColumn("Drives")
-            .AddColumn("GPUs");
-
-        foreach (var d in laptops)
-            table.AddRow(
-                d.Name,
-                (d.Cpus?.Count ?? 0).ToString(),
-                d.Ram == null ? "None" : $"{d.Ram.Size}GB",
-                (d.Drives?.Count ?? 0).ToString(),
-                (d.Gpus?.Count ?? 0).ToString()
-            );
-
-        AnsiConsole.Write(table);
-        return 0;
-    }
-}

+ 0 - 49
RackPeek/Commands/Laptops/LaptopReportCommand.cs

@@ -1,49 +0,0 @@
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Logging;
-using RackPeek.Domain.Resources.Hardware.Laptops;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops;
-
-public class LaptopReportCommand(
-    ILogger<LaptopReportCommand> logger,
-    IServiceProvider serviceProvider
-) : AsyncCommand
-{
-    public override async Task<int> ExecuteAsync(CommandContext context, CancellationToken cancellationToken)
-    {
-        using var scope = serviceProvider.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<LaptopHardwareReportUseCase>();
-
-        var report = await useCase.ExecuteAsync();
-
-        if (report.Laptops.Count == 0)
-        {
-            AnsiConsole.MarkupLine("[yellow]No Laptops found.[/]");
-            return 0;
-        }
-
-        var table = new Table()
-            .Border(TableBorder.Rounded)
-            .AddColumn("Name")
-            .AddColumn("CPU")
-            .AddColumn("C/T")
-            .AddColumn("RAM")
-            .AddColumn("Storage")
-            .AddColumn("GPU");
-
-        foreach (var d in report.Laptops)
-            table.AddRow(
-                d.Name,
-                d.CpuSummary,
-                $"{d.TotalCores}/{d.TotalThreads}",
-                $"{d.RamGb} GB",
-                $"{d.TotalStorageGb} GB (SSD {d.SsdStorageGb} / HDD {d.HddStorageGb})",
-                d.GpuSummary
-            );
-
-        AnsiConsole.Write(table);
-        return 0;
-    }
-}

+ 0 - 29
RackPeek/Commands/Laptops/LaptopTreeCommand.cs

@@ -1,29 +0,0 @@
-using RackPeek.Domain.Resources.Hardware;
-using Spectre.Console;
-using Spectre.Console.Cli;
-
-namespace RackPeek.Commands.Laptops;
-
-public sealed class LaptopTreeCommand(GetHardwareSystemTreeUseCase useCase)
-    : AsyncCommand<LaptopNameSettings>
-{
-    public override async Task<int> ExecuteAsync(
-        CommandContext context,
-        LaptopNameSettings settings,
-        CancellationToken cancellationToken)
-    {
-        var tree = await useCase.ExecuteAsync(settings.Name);
-
-        var root = new Tree($"[bold]{tree.Hardware.Name}[/]");
-
-        foreach (var system in tree.Systems)
-        {
-            var systemNode = root.AddNode($"[green]System:[/] {system.System.Name}");
-            foreach (var service in system.Services)
-                systemNode.AddNode($"[green]Service:[/] {service.Name}");
-        }
-
-        AnsiConsole.Write(root);
-        return 0;
-    }
-}

+ 0 - 29
RackPeek/Commands/Routers/Ports/RouterPortAddCommand.cs

@@ -1,29 +0,0 @@
-using Spectre.Console.Cli;
-using System.ComponentModel;
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Routers.Ports;
-using Spectre.Console;
-
-namespace RackPeek.Commands.Routers.Ports;
-
-public class RouterPortAddSettings : RouterNameSettings
-{
-    [CommandOption("--type")] public string? Type { get; set; }
-    [CommandOption("--speed")] public double? Speed { get; set; }
-    [CommandOption("--count")] public int? Count { get; set; }
-}
-
-public class RouterPortAddCommand(IServiceProvider sp)
-    : AsyncCommand<RouterPortAddSettings>
-{
-    public override async Task<int> ExecuteAsync(CommandContext ctx, RouterPortAddSettings s, CancellationToken ct)
-    {
-        using var scope = sp.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<AddRouterPortUseCase>();
-
-        await useCase.ExecuteAsync(s.Name, s.Type, s.Speed, s.Count);
-
-        AnsiConsole.MarkupLine($"[green]Port added to router '{s.Name}'.[/]");
-        return 0;
-    }
-}

+ 0 - 27
RackPeek/Commands/Routers/Ports/RouterPortRemoveCommand.cs

@@ -1,27 +0,0 @@
-using Spectre.Console.Cli;
-using System.ComponentModel;
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Routers.Ports;
-using Spectre.Console;
-
-namespace RackPeek.Commands.Routers.Ports;
-
-public class RouterPortRemoveSettings : RouterNameSettings
-{
-    [CommandOption("--index <INDEX>")] public int Index { get; set; }
-}
-
-public class RouterPortRemoveCommand(IServiceProvider sp)
-    : AsyncCommand<RouterPortRemoveSettings>
-{
-    public override async Task<int> ExecuteAsync(CommandContext ctx, RouterPortRemoveSettings s, CancellationToken ct)
-    {
-        using var scope = sp.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<RemoveRouterPortUseCase>();
-
-        await useCase.ExecuteAsync(s.Name, s.Index);
-
-        AnsiConsole.MarkupLine($"[green]Port {s.Index} removed from router '{s.Name}'.[/]");
-        return 0;
-    }
-}

+ 0 - 30
RackPeek/Commands/Routers/Ports/RouterPortUpdateCommand.cs

@@ -1,30 +0,0 @@
-using Spectre.Console.Cli;
-using System.ComponentModel;
-using Microsoft.Extensions.DependencyInjection;
-using RackPeek.Domain.Resources.Hardware.Routers.Ports;
-using Spectre.Console;
-
-namespace RackPeek.Commands.Routers.Ports;
-
-public class RouterPortUpdateSettings : RouterNameSettings
-{
-    [CommandOption("--index <INDEX>")] public int Index { get; set; }
-    [CommandOption("--type")] public string? Type { get; set; }
-    [CommandOption("--speed")] public double? Speed { get; set; }
-    [CommandOption("--count")] public int? Count { get; set; }
-}
-
-public class RouterPortUpdateCommand(IServiceProvider sp)
-    : AsyncCommand<RouterPortUpdateSettings>
-{
-    public override async Task<int> ExecuteAsync(CommandContext ctx, RouterPortUpdateSettings s, CancellationToken ct)
-    {
-        using var scope = sp.CreateScope();
-        var useCase = scope.ServiceProvider.GetRequiredService<UpdateRouterPortUseCase>();
-
-        await useCase.ExecuteAsync(s.Name, s.Index, s.Type, s.Speed, s.Count);
-
-        AnsiConsole.MarkupLine($"[green]Port {s.Index} updated on router '{s.Name}'.[/]");
-        return 0;
-    }
-}

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików