2026-03-31 07:27:15 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
namespace Core\Mod\Agentic\Actions\Fleet;
|
|
|
|
|
|
|
|
|
|
use Core\Actions\Action;
|
|
|
|
|
use Core\Mod\Agentic\Models\FleetNode;
|
|
|
|
|
use Core\Mod\Agentic\Models\FleetTask;
|
|
|
|
|
|
|
|
|
|
class GetFleetStats
|
|
|
|
|
{
|
|
|
|
|
use Action;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @return array<string, int>
|
|
|
|
|
*/
|
|
|
|
|
public function handle(int $workspaceId): array
|
|
|
|
|
{
|
|
|
|
|
$nodes = FleetNode::query()->where('workspace_id', $workspaceId);
|
|
|
|
|
$tasks = FleetTask::query()->where('workspace_id', $workspaceId);
|
2026-03-31 08:08:04 +00:00
|
|
|
$taskSamples = (clone $tasks)
|
|
|
|
|
->whereNotNull('started_at')
|
|
|
|
|
->get();
|
2026-03-31 07:27:15 +00:00
|
|
|
|
|
|
|
|
return [
|
|
|
|
|
'nodes_online' => (clone $nodes)->online()->count(),
|
|
|
|
|
'tasks_today' => (clone $tasks)->whereDate('created_at', today())->count(),
|
|
|
|
|
'tasks_week' => (clone $tasks)->where('created_at', '>=', now()->subDays(7))->count(),
|
|
|
|
|
'repos_touched' => (clone $tasks)->distinct('repo')->count('repo'),
|
|
|
|
|
'findings_total' => (clone $tasks)->get()->sum(static fn (FleetTask $task) => count($task->findings ?? [])),
|
2026-03-31 08:08:04 +00:00
|
|
|
'compute_hours' => (int) round(
|
|
|
|
|
$taskSamples->sum(fn (FleetTask $task) => self::taskDurationSeconds($task)) / 3600,
|
|
|
|
|
),
|
2026-03-31 07:27:15 +00:00
|
|
|
];
|
|
|
|
|
}
|
2026-03-31 08:08:04 +00:00
|
|
|
|
|
|
|
|
private static function taskDurationSeconds(FleetTask $fleetTask): int
|
|
|
|
|
{
|
|
|
|
|
if ($fleetTask->started_at === null) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return max(
|
|
|
|
|
0,
|
|
|
|
|
(int) $fleetTask->started_at->diffInSeconds($fleetTask->completed_at ?? now()),
|
|
|
|
|
);
|
|
|
|
|
}
|
2026-03-31 07:27:15 +00:00
|
|
|
}
|