60 lines
2.7 KiB
C#
60 lines
2.7 KiB
C#
using Nexus.Api.Data;
|
|
using Nexus.Api.Integrations;
|
|
using Nexus.Api.Repositories;
|
|
|
|
namespace Nexus.Api.Services;
|
|
|
|
public sealed class OperationsService(
|
|
IAgentRuntime runtime,
|
|
IAgentService agentService,
|
|
IProjectRepository projectRepo,
|
|
ITaskRepository taskRepo,
|
|
IActivityRepository activityRepo) : IOperationsService
|
|
{
|
|
public async Task<object> GetSnapshotAsync(CancellationToken ct = default)
|
|
{
|
|
var runtimeTask = runtime.GetStatusAsync(ct);
|
|
var agentsTask = agentService.GetAgentsAsync(ct);
|
|
// Repository calls share the scoped EF Core DbContext and must stay serialized.
|
|
var projects = await projectRepo.GetAllAsync(ct);
|
|
var tasks = await taskRepo.GetAllAsync(ct);
|
|
var activity = await activityRepo.GetRecentAsync(20, ct);
|
|
var agents = await agentsTask;
|
|
var completedTasks = tasks.Count(x => x.State == TaskStateHelper.ToStateString(TaskState.Done));
|
|
var runtimeStatus = await runtimeTask;
|
|
|
|
var lastIncident = tasks
|
|
.Where(x => x.State == TaskStateHelper.ToStateString(TaskState.Blocked))
|
|
.OrderByDescending(x => x.UpdatedAt)
|
|
.Select(x => new { TaskId = (Guid?)x.Id, Title = (string?)x.Title, Since = (DateTimeOffset?)x.UpdatedAt })
|
|
.FirstOrDefault();
|
|
|
|
return new
|
|
{
|
|
generatedAt = DateTimeOffset.UtcNow,
|
|
runtime = runtimeStatus,
|
|
models = Array.Empty<object>(),
|
|
runtimeHealthy = runtimeStatus.Status == OperationalStatus.Online,
|
|
metrics = new
|
|
{
|
|
activeAgents = agents.Count,
|
|
queuedTasks = tasks.Count - completedTasks,
|
|
successRate = tasks.Count == 0 ? 100 : Math.Round(completedTasks * 100d / tasks.Count, 1),
|
|
incidents = tasks.Count(x => x.State == TaskStateHelper.ToStateString(TaskState.Blocked))
|
|
},
|
|
lastIncident,
|
|
projectHealth = new
|
|
{
|
|
Online = projects.Count(x => x.Status == OperationalStatus.Online),
|
|
Offline = projects.Count(x => x.Status == OperationalStatus.Offline),
|
|
Degraded = projects.Count(x => x.Status == OperationalStatus.Degraded),
|
|
Unknown = projects.Count(x => x.Status == OperationalStatus.Unknown)
|
|
},
|
|
agents = agents.Select(x => new { x.Id, x.Name, x.Role, x.Status, x.Model }),
|
|
projects = projects.Select(x => new { x.Id, x.Name, x.Status, x.Progress, x.UpdatedAt }),
|
|
tasks = tasks.Select(x => new { x.Id, x.Title, x.State, x.Priority, x.ProjectId, x.UpdatedAt }),
|
|
activity = activity.Select(x => new { x.Id, x.Type, x.Message, at = x.CreatedAt })
|
|
};
|
|
}
|
|
}
|