feat(system): page Status avec endpoint API Platform et composants Vue
- Nouveau domaine System/Domain/Model/SystemStatus (value object) - QueryHandler agrégeant métriques mangas, chapitres, jobs (global/24h/7j), stockage et sources - Endpoint GET /api/system/status via API Platform (singleton) - Calcul de l'espace disque par RecursiveDirectoryIterator sur public/images - Page Vue /system/status avec 6 cards (Mangas, Chapitres, Jobs, Stockage, Sources, Système) - Nettoyage du router : suppression des PlaceholderComponent et routes placeholder - Sidebar : suppression des entrées sans page réelle
This commit is contained in:
parent
c2b55e9018
commit
ca8791cc0d
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace App\Domain\System\Application\QueryHandler;
|
||||
|
||||
use App\Domain\Shared\Domain\Contract\JobRepositoryInterface;
|
||||
use App\Domain\Shared\Domain\Model\JobStatus;
|
||||
use App\Domain\System\Application\Query\GetSystemStatusQuery;
|
||||
use App\Domain\System\Domain\Contract\Repository\SystemStatusRepositoryInterface;
|
||||
use App\Domain\System\Domain\Model\SystemStatus;
|
||||
|
||||
readonly class GetSystemStatusQueryHandler
|
||||
{
|
||||
public function __construct(
|
||||
private SystemStatusRepositoryInterface $systemStatusRepository,
|
||||
private JobRepositoryInterface $jobRepository,
|
||||
private string $mangaDataPath,
|
||||
private string $imagesStoragePath,
|
||||
) {
|
||||
}
|
||||
|
||||
public function handle(GetSystemStatusQuery $query): SystemStatus
|
||||
{
|
||||
$now = new \DateTimeImmutable();
|
||||
$last24h = $now->modify('-24 hours');
|
||||
$last7d = $now->modify('-7 days');
|
||||
|
||||
$totalJobs = $this->jobRepository->countByCriteria([]);
|
||||
$completedJobs = $this->jobRepository->countByCriteria(['status' => JobStatus::COMPLETED]);
|
||||
$failedJobs = $this->jobRepository->countByCriteria(['status' => JobStatus::FAILED]);
|
||||
$pendingJobs = $this->jobRepository->countByCriteria(['status' => JobStatus::PENDING]);
|
||||
$inProgressJobs = $this->jobRepository->countByCriteria(['status' => JobStatus::IN_PROGRESS]);
|
||||
|
||||
$totalJobsLast24h = $this->jobRepository->countByCriteria(['createdAfter' => $last24h]);
|
||||
$completedJobsLast24h = $this->jobRepository->countByCriteria(['status' => JobStatus::COMPLETED, 'createdAfter' => $last24h]);
|
||||
$failedJobsLast24h = $this->jobRepository->countByCriteria(['status' => JobStatus::FAILED, 'createdAfter' => $last24h]);
|
||||
|
||||
$totalJobsLast7d = $this->jobRepository->countByCriteria(['createdAfter' => $last7d]);
|
||||
$completedJobsLast7d = $this->jobRepository->countByCriteria(['status' => JobStatus::COMPLETED, 'createdAfter' => $last7d]);
|
||||
$failedJobsLast7d = $this->jobRepository->countByCriteria(['status' => JobStatus::FAILED, 'createdAfter' => $last7d]);
|
||||
|
||||
$storagePath = $this->imagesStoragePath;
|
||||
$storageTotalBytes = (int) (@disk_total_space($storagePath) ?: 0);
|
||||
$storageFreeBytes = (int) (@disk_free_space($storagePath) ?: 0);
|
||||
$storageUsedBytes = $this->computeDirectorySize($storagePath);
|
||||
|
||||
return new SystemStatus(
|
||||
totalMangas: $this->systemStatusRepository->countMangas(),
|
||||
monitoredMangas: $this->systemStatusRepository->countMonitoredMangas(),
|
||||
mangasByStatus: $this->systemStatusRepository->countMangasByStatus(),
|
||||
totalChapters: $this->systemStatusRepository->countChapters(),
|
||||
downloadedChapters: $this->systemStatusRepository->countDownloadedChapters(),
|
||||
totalJobs: $totalJobs,
|
||||
completedJobs: $completedJobs,
|
||||
failedJobs: $failedJobs,
|
||||
pendingJobs: $pendingJobs,
|
||||
inProgressJobs: $inProgressJobs,
|
||||
totalJobsLast24h: $totalJobsLast24h,
|
||||
completedJobsLast24h: $completedJobsLast24h,
|
||||
failedJobsLast24h: $failedJobsLast24h,
|
||||
totalJobsLast7d: $totalJobsLast7d,
|
||||
completedJobsLast7d: $completedJobsLast7d,
|
||||
failedJobsLast7d: $failedJobsLast7d,
|
||||
storagePath: $this->mangaDataPath,
|
||||
storageTotalBytes: $storageTotalBytes,
|
||||
storageFreeBytes: $storageFreeBytes,
|
||||
storageUsedBytes: $storageUsedBytes,
|
||||
totalSources: $this->systemStatusRepository->countContentSources(),
|
||||
sourcesByHealth: $this->systemStatusRepository->countContentSourcesByHealth(),
|
||||
phpVersion: PHP_VERSION,
|
||||
generatedAt: $now,
|
||||
);
|
||||
}
|
||||
|
||||
private function computeDirectorySize(string $path): int
|
||||
{
|
||||
if (!is_dir($path)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$size = 0;
|
||||
$iterator = new \RecursiveIteratorIterator(
|
||||
new \RecursiveDirectoryIterator($path, \FilesystemIterator::SKIP_DOTS)
|
||||
);
|
||||
|
||||
foreach ($iterator as $file) {
|
||||
if ($file->isFile()) {
|
||||
$size += $file->getSize();
|
||||
}
|
||||
}
|
||||
|
||||
return $size;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user