< Summary

Information
Class: Orchestrator.Commands.Utility.UploadKpi.UploadKpiCommand.KpiDocumentJson
Assembly: Orchestrator
File(s): /home/runner/work/KicktippAi/KicktippAi/src/Orchestrator/Commands/Utility/UploadKpi/UploadKpiCommand.cs
Line coverage
100%
Covered lines: 4
Uncovered lines: 0
Coverable lines: 4
Total lines: 146
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_DocumentName()100%11100%
set_DocumentName(...)100%11100%
.ctor()100%11100%
get_Content()100%11100%
set_Content(...)100%11100%
get_Description()100%11100%
set_Description(...)100%11100%
get_CommunityContext()100%11100%
set_CommunityContext(...)100%11100%

File(s)

/home/runner/work/KicktippAi/KicktippAi/src/Orchestrator/Commands/Utility/UploadKpi/UploadKpiCommand.cs

#LineLine coverage
 1using Microsoft.Extensions.DependencyInjection;
 2using Microsoft.Extensions.FileProviders;
 3using Microsoft.Extensions.Logging;
 4using Spectre.Console.Cli;
 5using Spectre.Console;
 6using System.Text.Json;
 7using EHonda.KicktippAi.Core;
 8using Orchestrator.Infrastructure;
 9using Orchestrator.Infrastructure.Factories;
 10
 11namespace Orchestrator.Commands.Utility.UploadKpi;
 12
 13public class UploadKpiCommand : AsyncCommand<UploadKpiSettings>
 14{
 15    private readonly IAnsiConsole _console;
 16    private readonly IFirebaseServiceFactory _firebaseServiceFactory;
 17    private readonly IFileProvider _fileProvider;
 18    private readonly ILogger<UploadKpiCommand> _logger;
 19
 20    public UploadKpiCommand(
 21        IAnsiConsole console,
 22        IFirebaseServiceFactory firebaseServiceFactory,
 23        [FromKeyedServices(ServiceRegistrationExtensions.KpiDocumentsFileProviderKey)] IFileProvider fileProvider,
 24        ILogger<UploadKpiCommand> logger)
 25    {
 26        _console = console;
 27        _firebaseServiceFactory = firebaseServiceFactory;
 28        _fileProvider = fileProvider;
 29        _logger = logger;
 30    }
 31
 32    public override async Task<int> ExecuteAsync(CommandContext context, UploadKpiSettings settings)
 33    {
 34        try
 35        {
 36            _console.MarkupLine($"[green]Upload KPI command initialized for document:[/] [yellow]{settings.DocumentName}
 37            _console.MarkupLine($"[blue]Using community context:[/] [yellow]{settings.CommunityContext}[/]");
 38
 39            if (settings.Verbose)
 40            {
 41                _console.MarkupLine("[dim]Verbose mode enabled[/]");
 42            }
 43
 44            // Check if the JSON file exists in the community-context specific subfolder
 45            var jsonFilePath = $"output/{settings.CommunityContext}/{settings.DocumentName}.json";
 46            var fileInfo = _fileProvider.GetFileInfo(jsonFilePath);
 47            if (!fileInfo.Exists)
 48            {
 49                _console.MarkupLine($"[red]KPI document file not found:[/] {jsonFilePath}");
 50                _console.MarkupLine($"[dim]Run the PowerShell script with firebase mode to create the document first.[/]
 51                return 1;
 52            }
 53
 54            _console.MarkupLine($"[blue]Reading KPI document from:[/] {jsonFilePath}");
 55
 56            // Read and parse the JSON file
 57            using var stream = fileInfo.CreateReadStream();
 58            var kpiDocument = await JsonSerializer.DeserializeAsync<KpiDocumentJson>(stream, new JsonSerializerOptions
 59            {
 60                PropertyNameCaseInsensitive = true
 61            });
 62
 63            if (kpiDocument == null)
 64            {
 65                _console.MarkupLine("[red]Failed to parse KPI document JSON[/]");
 66                return 1;
 67            }
 68
 69            if (settings.Verbose)
 70            {
 71                _console.MarkupLine($"[dim]Document Name: {kpiDocument.DocumentName}[/]");
 72                _console.MarkupLine($"[dim]Community Context: {kpiDocument.CommunityContext}[/]");
 73                _console.MarkupLine($"[dim]Content length: {kpiDocument.Content.Length} characters[/]");
 74            }
 75
 76            // Create Firebase services using factory (factory handles env var loading)
 77            var kpiRepository = _firebaseServiceFactory.CreateKpiRepository();
 78
 79            // Check if document already exists for this community context
 80            var existingDocument = await kpiRepository.GetKpiDocumentAsync(kpiDocument.DocumentName, kpiDocument.Communi
 81
 82            if (existingDocument != null)
 83            {
 84                _console.MarkupLine($"[blue]Found existing KPI document '{kpiDocument.DocumentName}' (version {existingD
 85                _console.MarkupLine($"[blue]Checking for content changes...[/]");
 86
 87                if (settings.Verbose)
 88                {
 89                    _console.MarkupLine($"[dim]Current content length: {existingDocument.Content.Length} characters[/]")
 90                    _console.MarkupLine($"[dim]New content length: {kpiDocument.Content.Length} characters[/]");
 91                }
 92            }
 93            else
 94            {
 95                _console.MarkupLine($"[blue]No existing KPI document found for '{kpiDocument.DocumentName}' - will creat
 96            }
 97
 98            // Upload the document (versioning is handled automatically by the repository)
 99            _console.MarkupLine($"[blue]Processing KPI document...[/]");
 100
 101            var savedVersion = await kpiRepository.SaveKpiDocumentAsync(
 102                kpiDocument.DocumentName,
 103                kpiDocument.Content,
 104                kpiDocument.Description,
 105                kpiDocument.CommunityContext);
 106
 107            if (existingDocument != null && savedVersion == existingDocument.Version)
 108            {
 109                _console.MarkupLine($"[green]✓ Content unchanged - KPI document '[/][white]{kpiDocument.DocumentName}[/]
 110            }
 111            else if (existingDocument != null)
 112            {
 113                _console.MarkupLine($"[green]✓ Content changed - Created new version {savedVersion} for KPI document '[/
 114            }
 115            else
 116            {
 117                _console.MarkupLine($"[green]✓ Successfully created KPI document '[/][white]{kpiDocument.DocumentName}[/
 118            }
 119
 120            if (settings.Verbose)
 121            {
 122                _console.MarkupLine($"[dim]Document saved to unified kpi-documents collection with community context: {k
 123                _console.MarkupLine($"[dim]Document version: {savedVersion}[/]");
 124            }
 125
 126            return 0;
 127        }
 128        catch (Exception ex)
 129        {
 130            _logger.LogError(ex, "Error in upload-kpi command");
 131            _console.MarkupLine($"[red]Error: {ex.Message}[/]");
 132            return 1;
 133        }
 134    }
 135
 136    /// <summary>
 137    /// JSON model for deserializing KPI document files.
 138    /// </summary>
 139    private class KpiDocumentJson
 140    {
 1141        public string DocumentName { get; set; } = string.Empty;
 1142        public string Content { get; set; } = string.Empty;
 1143        public string Description { get; set; } = string.Empty;
 1144        public string CommunityContext { get; set; } = string.Empty;
 145    }
 146}